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:
Dimitry Andric 2021-12-25 23:36:56 +01:00
commit 0eae32dcef
1628 changed files with 80126 additions and 46848 deletions

View File

@ -240,7 +240,7 @@ class ObjCContextInfo : public CommonTypeInfo {
} }
void setSwiftImportAsNonGeneric(llvm::Optional<bool> Value) { void setSwiftImportAsNonGeneric(llvm::Optional<bool> Value) {
SwiftImportAsNonGenericSpecified = Value.hasValue(); SwiftImportAsNonGenericSpecified = Value.hasValue();
SwiftImportAsNonGeneric = Value.hasValue() ? *Value : false; SwiftImportAsNonGeneric = Value.getValueOr(false);
} }
llvm::Optional<bool> getSwiftObjCMembers() const { llvm::Optional<bool> getSwiftObjCMembers() const {
@ -249,7 +249,7 @@ class ObjCContextInfo : public CommonTypeInfo {
} }
void setSwiftObjCMembers(llvm::Optional<bool> Value) { void setSwiftObjCMembers(llvm::Optional<bool> Value) {
SwiftObjCMembersSpecified = Value.hasValue(); SwiftObjCMembersSpecified = Value.hasValue();
SwiftObjCMembers = Value.hasValue() ? *Value : false; SwiftObjCMembers = Value.getValueOr(false);
} }
/// Strip off any information within the class information structure that is /// 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) { void setSwiftImportAsAccessors(llvm::Optional<bool> Value) {
SwiftImportAsAccessorsSpecified = Value.hasValue(); SwiftImportAsAccessorsSpecified = Value.hasValue();
SwiftImportAsAccessors = Value.hasValue() ? *Value : false; SwiftImportAsAccessors = Value.getValueOr(false);
} }
friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &); friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &);
@ -433,7 +433,7 @@ class ParamInfo : public VariableInfo {
} }
void setNoEscape(llvm::Optional<bool> Value) { void setNoEscape(llvm::Optional<bool> Value) {
NoEscapeSpecified = Value.hasValue(); NoEscapeSpecified = Value.hasValue();
NoEscape = Value.hasValue() ? *Value : false; NoEscape = Value.getValueOr(false);
} }
llvm::Optional<RetainCountConventionKind> getRetainCountConvention() const { llvm::Optional<RetainCountConventionKind> getRetainCountConvention() const {
@ -671,7 +671,7 @@ class TagInfo : public CommonTypeInfo {
} }
void setFlagEnum(llvm::Optional<bool> Value) { void setFlagEnum(llvm::Optional<bool> Value) {
HasFlagEnum = Value.hasValue(); HasFlagEnum = Value.hasValue();
IsFlagEnum = Value.hasValue() ? *Value : false; IsFlagEnum = Value.getValueOr(false);
} }
TagInfo &operator|=(const TagInfo &RHS) { TagInfo &operator|=(const TagInfo &RHS) {

View File

@ -248,6 +248,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&> mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
TemplateSpecializationTypes; TemplateSpecializationTypes;
mutable llvm::FoldingSet<ParenType> ParenTypes; mutable llvm::FoldingSet<ParenType> ParenTypes;
mutable llvm::FoldingSet<UsingType> UsingTypes;
mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes; mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
mutable llvm::FoldingSet<DependentNameType> DependentNameTypes; mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType, mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
@ -264,8 +265,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<AtomicType> AtomicTypes; mutable llvm::FoldingSet<AtomicType> AtomicTypes;
llvm::FoldingSet<AttributedType> AttributedTypes; llvm::FoldingSet<AttributedType> AttributedTypes;
mutable llvm::FoldingSet<PipeType> PipeTypes; mutable llvm::FoldingSet<PipeType> PipeTypes;
mutable llvm::FoldingSet<ExtIntType> ExtIntTypes; mutable llvm::FoldingSet<BitIntType> BitIntTypes;
mutable llvm::FoldingSet<DependentExtIntType> DependentExtIntTypes; mutable llvm::FoldingSet<DependentBitIntType> DependentBitIntTypes;
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames; mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames; mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
@ -1350,13 +1351,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Return a write_only pipe type for the specified type. /// Return a write_only pipe type for the specified type.
QualType getWritePipeType(QualType T) const; 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. /// 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 /// Return a dependent bit-precise integer type with the specified signedness
/// bit count. /// and bit count.
QualType getDependentExtIntType(bool Unsigned, Expr *BitsExpr) const; QualType getDependentBitIntType(bool Unsigned, Expr *BitsExpr) const;
/// Gets the struct used to keep track of the extended descriptor for /// Gets the struct used to keep track of the extended descriptor for
/// pointer to blocks. /// pointer to blocks.
@ -1555,6 +1556,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
return getTypeDeclTypeSlow(Decl); return getTypeDeclTypeSlow(Decl);
} }
QualType getUsingType(const UsingShadowDecl *Found,
QualType Underlying) const;
/// Return the unique reference to the type for the specified /// Return the unique reference to the type for the specified
/// typedef-name decl. /// typedef-name decl.
QualType getTypedefType(const TypedefNameDecl *Decl, QualType getTypedefType(const TypedefNameDecl *Decl,
@ -1564,6 +1568,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getEnumType(const EnumDecl *Decl) const; QualType getEnumType(const EnumDecl *Decl) const;
QualType
getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const;
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const; QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
QualType getAttributedType(attr::Kind attrKind, QualType getAttributedType(attr::Kind attrKind,

View File

@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_AST_ASTDIAGNOSTIC_H #ifndef LLVM_CLANG_AST_ASTDIAGNOSTIC_H
#define LLVM_CLANG_AST_ASTDIAGNOSTIC_H #define LLVM_CLANG_AST_ASTDIAGNOSTIC_H
#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h" #include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticAST.h" #include "clang/Basic/DiagnosticAST.h"
@ -31,6 +32,11 @@ namespace clang {
SmallVectorImpl<char> &Output, SmallVectorImpl<char> &Output,
void *Cookie, void *Cookie,
ArrayRef<intptr_t> QualTypeVals); 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 } // end namespace clang
#endif #endif

View File

@ -75,6 +75,10 @@ class ASTImporterLookupTable {
// The function should be called when the old context is definitely different // The function should be called when the old context is definitely different
// from the new. // from the new.
void update(NamedDecl *ND, DeclContext *OldDC); 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; using LookupResult = DeclList;
LookupResult lookup(DeclContext *DC, DeclarationName Name) const; LookupResult lookup(DeclContext *DC, DeclarationName Name) const;
// Check if the `ND` is within the lookup table (with its current name) in // Check if the `ND` is within the lookup table (with its current name) in

View File

@ -21,7 +21,7 @@ inline T makeNullableFromOptional(const Optional<T> &value) {
template <class T> template <class T>
inline T *makePointerFromOptional(Optional<T *> value) { inline T *makePointerFromOptional(Optional<T *> value) {
return (value ? *value : nullptr); return value.getValueOr(nullptr);
} }
// PropertyReader is a class concept that requires the following method: // PropertyReader is a class concept that requires the following method:

View File

@ -1211,13 +1211,12 @@ class TemplateTypeParmDecl final : public TypeDecl,
DefArgStorage DefaultArgument; DefArgStorage DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc, TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
SourceLocation IdLoc, IdentifierInfo *Id, SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
bool Typename, bool HasTypeConstraint, bool HasTypeConstraint, Optional<unsigned> NumExpanded)
Optional<unsigned> NumExpanded)
: TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename), : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false), HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
ExpandedParameterPack(NumExpanded), ExpandedParameterPack(NumExpanded),
NumExpanded(NumExpanded ? *NumExpanded : 0) {} NumExpanded(NumExpanded.getValueOr(0)) {}
public: public:
static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC, static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,

View File

@ -572,6 +572,12 @@ class Expr : public ValueStmt {
bool isConstantInitializer(ASTContext &Ctx, bool ForRef, bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
const Expr **Culprit = nullptr) const; 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. /// EvalStatus is a struct with detailed info about an evaluation in progress.
struct EvalStatus { struct EvalStatus {
/// Whether the evaluated expression has side effects. /// Whether the evaluated expression has side effects.

View File

@ -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' /// This represents 'seq_cst' clause in the '#pragma omp atomic'
/// directive. /// directive.
/// ///

View File

@ -107,6 +107,8 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>; SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
def TemplateTemplateParmDeclRef : def TemplateTemplateParmDeclRef :
SubclassPropertyType<"TemplateTemplateParmDecl", DeclRef>; SubclassPropertyType<"TemplateTemplateParmDecl", DeclRef>;
def UsingShadowDeclRef :
SubclassPropertyType<"UsingShadowDecl", DeclRef>;
def ValueDeclRef : def ValueDeclRef :
SubclassPropertyType<"ValueDecl", DeclRef>; SubclassPropertyType<"ValueDecl", DeclRef>;
def ElaboratedTypeKeyword : EnumPropertyType; def ElaboratedTypeKeyword : EnumPropertyType;

View File

@ -981,6 +981,7 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
TRY_TO(TraverseStmt(NE)); TRY_TO(TraverseStmt(NE));
}) })
DEF_TRAVERSE_TYPE(UsingType, {})
DEF_TRAVERSE_TYPE(UnresolvedUsingType, {}) DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
DEF_TRAVERSE_TYPE(TypedefType, {}) 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(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
DEF_TRAVERSE_TYPE(ExtIntType, {}) DEF_TRAVERSE_TYPE(BitIntType, {})
DEF_TRAVERSE_TYPE(DependentExtIntType, DEF_TRAVERSE_TYPE(DependentBitIntType,
{ TRY_TO(TraverseStmt(T->getNumBitsExpr())); }) { TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
#undef DEF_TRAVERSE_TYPE #undef DEF_TRAVERSE_TYPE
@ -1252,6 +1253,7 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
TRY_TO(TraverseStmt(NE)); TRY_TO(TraverseStmt(NE));
}) })
DEF_TRAVERSE_TYPELOC(UsingType, {})
DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {}) DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
DEF_TRAVERSE_TYPELOC(TypedefType, {}) 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(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
DEF_TRAVERSE_TYPELOC(ExtIntType, {}) DEF_TRAVERSE_TYPELOC(BitIntType, {})
DEF_TRAVERSE_TYPELOC(DependentExtIntType, { DEF_TRAVERSE_TYPELOC(DependentBitIntType, {
TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr())); TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
}) })
@ -2095,7 +2097,13 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
} }
if (VisitBody) { 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; return true;
} }
@ -3226,6 +3234,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
return true; return true;
} }
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPCompareClause(OMPCompareClause *) {
return true;
}
template <typename Derived> template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) { bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
return true; return true;

View File

@ -311,6 +311,7 @@ class TextNodeDumper
void VisitFunctionType(const FunctionType *T); void VisitFunctionType(const FunctionType *T);
void VisitFunctionProtoType(const FunctionProtoType *T); void VisitFunctionProtoType(const FunctionProtoType *T);
void VisitUnresolvedUsingType(const UnresolvedUsingType *T); void VisitUnresolvedUsingType(const UnresolvedUsingType *T);
void VisitUsingType(const UsingType *T);
void VisitTypedefType(const TypedefType *T); void VisitTypedefType(const TypedefType *T);
void VisitUnaryTransformType(const UnaryTransformType *T); void VisitUnaryTransformType(const UnaryTransformType *T);
void VisitTagType(const TagType *T); void VisitTagType(const TagType *T);

View File

@ -129,6 +129,7 @@ class TemplateArgumentLoc;
class TemplateTypeParmDecl; class TemplateTypeParmDecl;
class TypedefNameDecl; class TypedefNameDecl;
class UnresolvedUsingTypenameDecl; class UnresolvedUsingTypenameDecl;
class UsingShadowDecl;
using CanQualType = CanQual<Type>; using CanQualType = CanQual<Type>;
@ -2128,7 +2129,7 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
bool isOCLExtOpaqueType() const; // Any OpenCL extension type bool isOCLExtOpaqueType() const; // Any OpenCL extension type
bool isPipeType() const; // OpenCL pipe 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 bool isOpenCLSpecificType() const; // Any OpenCL specific type
/// Determines if this type, which must satisfy /// 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 { class TypedefType : public Type {
TypedefNameDecl *Decl; TypedefNameDecl *Decl;
@ -6307,13 +6329,13 @@ class PipeType : public Type, public llvm::FoldingSetNode {
}; };
/// A fixed int type of a specified bitwidth. /// 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; friend class ASTContext;
unsigned IsUnsigned : 1; unsigned IsUnsigned : 1;
unsigned NumBits : 24; unsigned NumBits : 24;
protected: protected:
ExtIntType(bool isUnsigned, unsigned NumBits); BitIntType(bool isUnsigned, unsigned NumBits);
public: public:
bool isUnsigned() const { return IsUnsigned; } bool isUnsigned() const { return IsUnsigned; }
@ -6333,16 +6355,16 @@ class ExtIntType final : public Type, public llvm::FoldingSetNode {
ID.AddInteger(NumBits); 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; friend class ASTContext;
const ASTContext &Context; const ASTContext &Context;
llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned; llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned;
protected: protected:
DependentExtIntType(const ASTContext &Context, bool IsUnsigned, DependentBitIntType(const ASTContext &Context, bool IsUnsigned,
Expr *NumBits); Expr *NumBits);
public: public:
@ -6360,7 +6382,7 @@ class DependentExtIntType final : public Type, public llvm::FoldingSetNode {
bool IsUnsigned, Expr *NumBitsExpr); bool IsUnsigned, Expr *NumBitsExpr);
static bool classof(const Type *T) { 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); return isa<PipeType>(CanonicalType);
} }
inline bool Type::isExtIntType() const { inline bool Type::isBitIntType() const {
return isa<ExtIntType>(CanonicalType); return isa<BitIntType>(CanonicalType);
} }
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
@ -6998,7 +7020,7 @@ inline bool Type::isIntegerType() const {
return IsEnumDeclComplete(ET->getDecl()) && return IsEnumDeclComplete(ET->getDecl()) &&
!IsEnumDeclScoped(ET->getDecl()); !IsEnumDeclScoped(ET->getDecl());
} }
return isExtIntType(); return isBitIntType();
} }
inline bool Type::isFixedPointType() const { inline bool Type::isFixedPointType() const {
@ -7056,7 +7078,7 @@ inline bool Type::isScalarType() const {
isa<MemberPointerType>(CanonicalType) || isa<MemberPointerType>(CanonicalType) ||
isa<ComplexType>(CanonicalType) || isa<ComplexType>(CanonicalType) ||
isa<ObjCObjectPointerType>(CanonicalType) || isa<ObjCObjectPointerType>(CanonicalType) ||
isExtIntType(); isBitIntType();
} }
inline bool Type::isIntegralOrEnumerationType() const { inline bool Type::isIntegralOrEnumerationType() const {
@ -7069,7 +7091,7 @@ inline bool Type::isIntegralOrEnumerationType() const {
if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
return IsEnumDeclComplete(ET->getDecl()); return IsEnumDeclComplete(ET->getDecl());
return isExtIntType(); return isBitIntType();
} }
inline bool Type::isBooleanType() const { inline bool Type::isBooleanType() const {

View File

@ -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. /// Wrapper for source info for typedefs.
class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TypedefTypeLoc, TypedefTypeLoc,
@ -2561,12 +2571,12 @@ inline T TypeLoc::getAsAdjusted() const {
} }
return Cur.getAs<T>(); return Cur.getAs<T>();
} }
class ExtIntTypeLoc final class BitIntTypeLoc final
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ExtIntTypeLoc, : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, BitIntTypeLoc,
ExtIntType> {}; BitIntType> {};
class DependentExtIntTypeLoc final class DependentBitIntTypeLoc final
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentExtIntTypeLoc, : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentBitIntTypeLoc,
DependentExtIntType> {}; DependentBitIntType> {};
} // namespace clang } // namespace clang

View File

@ -358,7 +358,20 @@ let Class = UnresolvedUsingType in {
} }
def : Creator<[{ 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> { def : Property<"isUnsigned", Bool> {
let Read = [{ node->isUnsigned() }]; let Read = [{ node->isUnsigned() }];
} }
@ -891,11 +904,11 @@ let Class = ExtIntType in {
} }
def : Creator<[{ def : Creator<[{
return ctx.getExtIntType(isUnsigned, numBits); return ctx.getBitIntType(isUnsigned, numBits);
}]>; }]>;
} }
let Class = DependentExtIntType in { let Class = DependentBitIntType in {
def : Property<"isUnsigned", Bool> { def : Property<"isUnsigned", Bool> {
let Read = [{ node->isUnsigned() }]; let Read = [{ node->isUnsigned() }];
} }
@ -903,6 +916,6 @@ let Class = DependentExtIntType in {
let Read = [{ node->getNumBitsExpr() }]; let Read = [{ node->getNumBitsExpr() }];
} }
def : Creator<[{ def : Creator<[{
return ctx.getDependentExtIntType(isUnsigned, numBitsExpr); return ctx.getDependentBitIntType(isUnsigned, numBitsExpr);
}]>; }]>;
} }

View File

@ -4128,25 +4128,34 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
InnerMatcher.matches(*DeclNode, Finder, Builder)); InnerMatcher.matches(*DeclNode, Finder, Builder));
} }
/// Matches a \c DeclRefExpr that refers to a declaration through a /// Matches if a node refers to a declaration through a specific
/// specific using shadow declaration. /// using shadow declaration.
/// ///
/// Given /// Examples:
/// \code /// \code
/// namespace a { void f() {} } /// namespace a { int f(); }
/// using a::f; /// using a::f;
/// void g() { /// int x = f();
/// f(); // Matches this ..
/// a::f(); // .. but not this.
/// }
/// \endcode /// \endcode
/// declRefExpr(throughUsingDecl(anything())) /// declRefExpr(throughUsingDecl(anything()))
/// matches \c f() /// matches \c f
AST_MATCHER_P(DeclRefExpr, throughUsingDecl, ///
internal::Matcher<UsingShadowDecl>, InnerMatcher) { /// \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(); const NamedDecl *FoundDecl = Node.getFoundDecl();
if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl)) if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
return InnerMatcher.matches(*UsingDecl, Finder, Builder); return Inner.matches(*UsingDecl, Finder, Builder);
return false; return false;
} }
@ -4872,7 +4881,7 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,
} }
} }
int ParamIndex = 0; unsigned ParamIndex = 0;
bool Matched = false; bool Matched = false;
unsigned NumArgs = Node.getNumArgs(); unsigned NumArgs = Node.getNumArgs();
if (FProto && FProto->isVariadic()) 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. // This test is cheaper compared to the big matcher in the next if.
// Therefore, please keep this order. // Therefore, please keep this order.
if (FProto) { if (FProto && FProto->getNumParams() > ParamIndex) {
QualType ParamType = FProto->getParamType(ParamIndex); QualType ParamType = FProto->getParamType(ParamIndex);
if (ParamMatcher.matches(ParamType, Finder, &ParamMatches)) { if (ParamMatcher.matches(ParamType, Finder, &ParamMatches)) {
Result.addMatch(ParamMatches); Result.addMatch(ParamMatches);
@ -6843,7 +6852,7 @@ extern const AstTypeMatcher<DecltypeType> decltypeType;
AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType, AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType)); 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 /// Given
/// \code /// \code
@ -6853,9 +6862,10 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
/// decltypeType(hasUnderlyingType(isInteger())) /// decltypeType(hasUnderlyingType(isInteger()))
/// matches the type of "a" /// matches the type of "a"
/// ///
/// Usable as: Matcher<DecltypeType> /// Usable as: Matcher<DecltypeType>, Matcher<UsingType>
AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType, AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,
AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType)); AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType,
UsingType));
/// Matches \c FunctionType nodes. /// Matches \c FunctionType nodes.
/// ///
@ -7183,6 +7193,18 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
return InnerMatcher.matches(Node.getNamedType(), Finder, Builder); 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 /// Matches types that represent the result of substituting a type for a
/// template type parameter. /// template type parameter.
/// ///

View File

@ -1090,6 +1090,12 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
if (const auto *S = dyn_cast<ElaboratedType>(&Node)) { if (const auto *S = dyn_cast<ElaboratedType>(&Node)) {
return matchesSpecialized(S->desugar(), Finder, Builder); 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; return false;
} }

View File

@ -155,7 +155,7 @@ class CFGWalker {
return false; return false;
// Ignore anonymous functions. // Ignore anonymous functions.
if (!dyn_cast_or_null<NamedDecl>(AC.getDecl())) if (!isa_and_nonnull<NamedDecl>(AC.getDecl()))
return false; return false;
SortedGraph = AC.getAnalysis<PostOrderCFGView>(); SortedGraph = AC.getAnalysis<PostOrderCFGView>();

View File

@ -15,11 +15,20 @@
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
namespace clang { namespace clang {
namespace dataflow { namespace dataflow {
/// Holds the state of the program (store and heap) at a given program point. /// 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 dataflow
} // namespace clang } // namespace clang

View File

@ -61,11 +61,12 @@ struct ReversePostOrderCompare {
/// the same block multiple times at once. /// the same block multiple times at once.
struct ForwardDataflowWorklist struct ForwardDataflowWorklist
: DataflowWorklistBase<ReversePostOrderCompare, 20> { : DataflowWorklistBase<ReversePostOrderCompare, 20> {
ForwardDataflowWorklist(const CFG &Cfg, PostOrderCFGView *POV)
: DataflowWorklistBase(Cfg, POV,
ReversePostOrderCompare{POV->getComparator()}) {}
ForwardDataflowWorklist(const CFG &Cfg, AnalysisDeclContext &Ctx) ForwardDataflowWorklist(const CFG &Cfg, AnalysisDeclContext &Ctx)
: DataflowWorklistBase( : ForwardDataflowWorklist(Cfg, Ctx.getAnalysis<PostOrderCFGView>()) {}
Cfg, Ctx.getAnalysis<PostOrderCFGView>(),
ReversePostOrderCompare{
Ctx.getAnalysis<PostOrderCFGView>()->getComparator()}) {}
void enqueueSuccessors(const CFGBlock *Block) { void enqueueSuccessors(const CFGBlock *Block) {
for (auto B : Block->succs()) for (auto B : Block->succs())

View File

@ -76,6 +76,24 @@ struct TypeErasedDataflowAnalysisState {
Environment Env; 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 /// Performs dataflow analysis and returns a mapping from basic block IDs to
/// dataflow analysis states that model the respective basic blocks. Indices /// dataflow analysis states that model the respective basic blocks. Indices
/// of the returned vector correspond to basic block IDs. /// of the returned vector correspond to basic block IDs.

View File

@ -3865,6 +3865,14 @@ def ReleaseHandle : InheritableParamAttr {
let Documentation = [ReleaseHandleDocs]; 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 { def Builtin : InheritableAttr {
let Spellings = []; let Spellings = [];
let Args = [UnsignedArgument<"ID">]; let Args = [UnsignedArgument<"ID">];

View File

@ -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 are imported from external modules. See the dllimport_ documentation on MSDN
for more information. 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 .. _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 { def ArmSveVectorBitsDocs : Documentation {
let Category = DocCatType; let Category = DocCatType;
let Content = [{ let Content = [{

View File

@ -646,8 +646,10 @@ BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
BUILTIN(__builtin_elementwise_abs, "v.", "nct") BUILTIN(__builtin_elementwise_abs, "v.", "nct")
BUILTIN(__builtin_elementwise_max, "v.", "nct") BUILTIN(__builtin_elementwise_max, "v.", "nct")
BUILTIN(__builtin_elementwise_min, "v.", "nct") BUILTIN(__builtin_elementwise_min, "v.", "nct")
BUILTIN(__builtin_elementwise_ceil, "v.", "nct")
BUILTIN(__builtin_reduce_max, "v.", "nct") BUILTIN(__builtin_reduce_max, "v.", "nct")
BUILTIN(__builtin_reduce_min, "v.", "nct") BUILTIN(__builtin_reduce_min, "v.", "nct")
BUILTIN(__builtin_reduce_xor, "v.", "nct")
BUILTIN(__builtin_matrix_transpose, "v.", "nFt") BUILTIN(__builtin_matrix_transpose, "v.", "nFt")
BUILTIN(__builtin_matrix_column_major_load, "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). // Clang builtins (not available in GCC).
BUILTIN(__builtin_addressof, "v*v&", "nct") BUILTIN(__builtin_addressof, "v*v&", "nct")
BUILTIN(__builtin_function_start, "v*v&", "nct")
BUILTIN(__builtin_operator_new, "v*z", "tc") BUILTIN(__builtin_operator_new, "v*z", "tc")
BUILTIN(__builtin_operator_delete, "vv*", "tn") BUILTIN(__builtin_operator_delete, "vv*", "tn")
BUILTIN(__builtin_char_memchr, "c*cC*iz", "n") 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_begin, "v*v*", "n", COR_LANG)
LANGBUILTIN(__builtin_coro_end, "bv*Ib", "n", COR_LANG) LANGBUILTIN(__builtin_coro_end, "bv*Ib", "n", COR_LANG)
LANGBUILTIN(__builtin_coro_suspend, "cIb", "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. // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
// We need the generic prototype, since the packet type could be anything. // We need the generic prototype, since the packet type could be anything.

View File

@ -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

View File

@ -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

View File

@ -17,8 +17,10 @@
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) # define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif #endif
#pragma push_macro("V69")
#define V69 "v69"
#pragma push_macro("V68") #pragma push_macro("V68")
#define V68 "v68" #define V68 "v68|" V69
#pragma push_macro("V67") #pragma push_macro("V67")
#define V67 "v67|" V68 #define V67 "v67|" V68
#pragma push_macro("V66") #pragma push_macro("V66")
@ -34,8 +36,10 @@
#pragma push_macro("V5") #pragma push_macro("V5")
#define V5 "v5|" V55 #define V5 "v5|" V55
#pragma push_macro("HVXV69")
#define HVXV69 "hvxv69"
#pragma push_macro("HVXV68") #pragma push_macro("HVXV68")
#define HVXV68 "hvxv68" #define HVXV68 "hvxv68|" HVXV69
#pragma push_macro("HVXV67") #pragma push_macro("HVXV67")
#define HVXV67 "hvxv67|" HVXV68 #define HVXV67 "hvxv67|" HVXV68
#pragma push_macro("HVXV66") #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("HVXV66")
#pragma pop_macro("HVXV67") #pragma pop_macro("HVXV67")
#pragma pop_macro("HVXV68") #pragma pop_macro("HVXV68")
#pragma pop_macro("HVXV69")
#pragma pop_macro("V5") #pragma pop_macro("V5")
#pragma pop_macro("V55") #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("V66")
#pragma pop_macro("V67") #pragma pop_macro("V67")
#pragma pop_macro("V68") #pragma pop_macro("V68")
#pragma pop_macro("V69")
#undef BUILTIN #undef BUILTIN
#undef TARGET_BUILTIN #undef TARGET_BUILTIN

View File

@ -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_128B, "V64iV64iV64iUIi", "", HVXV68)
TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10_vxx, "V32iV32iV32iV32iUIi", "", 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_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)

View File

@ -8,199 +8,7 @@
// Automatically generated file, do not edit! // 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, 64)
CUSTOM_BUILTIN_MAPPING(V6_vaddcarry_128B, 128) 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, 64)
CUSTOM_BUILTIN_MAPPING(V6_vsubcarry_128B, 128) 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)

View File

@ -15,6 +15,7 @@
#define GET_SVE_BUILTINS #define GET_SVE_BUILTINS
#include "clang/Basic/arm_sve_builtins.inc" #include "clang/Basic/arm_sve_builtins.inc"
#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"
#undef GET_SVE_BUILTINS #undef GET_SVE_BUILTINS
#undef BUILTIN #undef BUILTIN

View File

@ -368,9 +368,6 @@ ENUM_CODEGENOPT(DebuggerTuning, llvm::DebuggerKind, 3,
/// emitted. /// emitted.
VALUE_CODEGENOPT(DwarfVersion, 3, 0) 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 /// Whether we should emit CodeView debug information. It's possible to emit
/// CodeView and DWARF into the same object. /// CodeView and DWARF into the same object.
CODEGENOPT(EmitCodeView, 1, 0) CODEGENOPT(EmitCodeView, 1, 0)

View File

@ -227,6 +227,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// Output filename for the split debug info, not used in the skeleton CU. /// Output filename for the split debug info, not used in the skeleton CU.
std::string SplitDwarfOutput; std::string SplitDwarfOutput;
/// Output filename used in the COFF debug information.
std::string ObjectFilenameForDebug;
/// The name of the relocation model to use. /// The name of the relocation model to use.
llvm::Reloc::Model RelocationModel; llvm::Reloc::Model RelocationModel;
@ -395,7 +398,7 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// Executable and command-line used to create a given CompilerInvocation. /// Executable and command-line used to create a given CompilerInvocation.
/// Most of the time this will be the full -cc1 command. /// Most of the time this will be the full -cc1 command.
const char *Argv0 = nullptr; 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 /// The minimum hotness value a diagnostic needs in order to be included in
/// optimization diagnostics. /// optimization diagnostics.

View File

@ -95,6 +95,8 @@ enum class CudaArch {
GFX1033, GFX1033,
GFX1034, GFX1034,
GFX1035, GFX1035,
Generic, // A processor model named 'generic' if the target backend defines a
// public one.
LAST, LAST,
}; };
@ -103,7 +105,8 @@ static inline bool IsNVIDIAGpuArch(CudaArch A) {
} }
static inline bool IsAMDGpuArch(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); const char *CudaArchToString(CudaArch A);

View File

@ -74,6 +74,14 @@ def err_drv_no_hip_runtime : Error<
"cannot find HIP runtime; provide its path via '--rocm-path', or pass " "cannot find HIP runtime; provide its path via '--rocm-path', or pass "
"'-nogpuinc' to build without HIP runtime">; "'-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< def err_drv_undetermined_amdgpu_arch : Error<
"cannot determine AMDGPU architecture: %0; consider passing it via " "cannot determine AMDGPU architecture: %0; consider passing it via "
"'--march'">; "'--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'">, "ignoring '%0' option as it is not currently supported for target '%1'">,
InGroup<OptionIgnored>; 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< def err_drv_invalid_thread_model_for_target : Error<
"invalid thread model '%0' in '%1' for this target">; "invalid thread model '%0' in '%1' for this target">;
def err_drv_invalid_linker_name : Error< 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< def err_analyzer_checker_incompatible_analyzer_option : Error<
"checker cannot be enabled with analyzer option '%0' == %1">; "checker cannot be enabled with analyzer option '%0' == %1">;
def err_drv_invalid_hvx_length : Error< def warn_drv_needs_hvx : Warning<
"-mhvx-length is not supported without a -mhvx/-mhvx= flag">; "%0 requires HVX, use -mhvx/-mhvx= to enable it">,
def warn_drv_vectorize_needs_hvx : Warning<
"auto-vectorization requires HVX, use -mhvx to enable it">,
InGroup<OptionIgnored>; 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< def err_drv_module_header_wrong_kind : Error<
"header file '%0' input type '%1' does not match type of prior input " "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>; InGroup<OptionIgnored>;
def warn_drv_moutline_atomics_unsupported_opt : Warning< 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>; InGroup<OptionIgnored>;
def warn_drv_darwin_sdk_invalid_settings : Warning< 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">; "generated arguments parse failed in round-trip">;
def err_cc1_round_trip_mismatch : Error< def err_cc1_round_trip_mismatch : Error<
"generated arguments do not match in round-trip">; "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< def err_drv_ssp_missing_offset_argument : Error<
"'%0' is used without '-mstack-protector-guard-offset', and there is no default">; "'%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'.">;
} }

View File

@ -191,6 +191,7 @@ def DeprecatedVolatile : DiagGroup<"deprecated-volatile">;
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings", def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
[CXX11CompatDeprecatedWritableStr]>; [CXX11CompatDeprecatedWritableStr]>;
def DeprecatedPragma : DiagGroup<"deprecated-pragma">; def DeprecatedPragma : DiagGroup<"deprecated-pragma">;
def DeprecatedType : DiagGroup<"deprecated-type">;
// FIXME: Why is DeprecatedImplementations not in this group? // FIXME: Why is DeprecatedImplementations not in this group?
def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion, def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
DeprecatedArrayCompare, DeprecatedArrayCompare,
@ -208,6 +209,7 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
DeprecatedPragma, DeprecatedPragma,
DeprecatedRegister, DeprecatedRegister,
DeprecatedThisCapture, DeprecatedThisCapture,
DeprecatedType,
DeprecatedVolatile, DeprecatedVolatile,
DeprecatedWritableStr]>, DeprecatedWritableStr]>,
DiagCategory<"Deprecations">; DiagCategory<"Deprecations">;
@ -1044,6 +1046,13 @@ def : DiagGroup<"unused-local-typedefs", [UnusedLocalTypedef]>;
def NonGCC : DiagGroup<"non-gcc", def NonGCC : DiagGroup<"non-gcc",
[SignCompare, Conversion, LiteralRange]>; [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 // A warning group for warnings about using C++11 features as extensions in
// earlier C++ versions. // earlier C++ versions.
def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNamespace, 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 // A warning group for warnings about using C++14 features as extensions in
// earlier C++ versions. // 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 // A warning group for warnings about using C++17 features as extensions in
// earlier C++ versions. // 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 // A warning group for warnings about using C++20 features as extensions in
// earlier C++ versions. // 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 // A warning group for warnings about using C++2b features as extensions in
// earlier C++ versions. // earlier C++ versions.

View File

@ -1503,6 +1503,15 @@ def warn_pragma_force_cuda_host_device_bad_arg : Warning<
def err_pragma_cannot_end_force_cuda_host_device : Error< def err_pragma_cannot_end_force_cuda_host_device : Error<
"force_cuda_host_device end pragma without matching " "force_cuda_host_device end pragma without matching "
"force_cuda_host_device begin">; "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. } // end of Parse Issue category.
let CategoryName = "Modules Issue" in { let CategoryName = "Modules Issue" in {

View File

@ -838,6 +838,9 @@ def warn_fortify_scanf_overflow : Warning<
"%2, but the corresponding specifier may require size %3">, "%2, but the corresponding specifier may require size %3">,
InGroup<FortifySource>; InGroup<FortifySource>;
def err_function_start_invalid_type: Error<
"argument must be a function">;
/// main() /// main()
// static main() is not an error in C, just in C++. // static main() is not an error in C, just in C++.
def warn_static_main : Warning<"'main' should not be declared static">, 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< def err_attribute_wrong_number_arguments : Error<
"%0 attribute %plural{0:takes no arguments|1:takes one argument|" "%0 attribute %plural{0:takes no arguments|1:takes one argument|"
":requires exactly %1 arguments}1">; ":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< def err_attribute_too_many_arguments : Error<
"%0 attribute takes no more than %1 argument%s1">; "%0 attribute takes no more than %1 argument%s1">;
def err_attribute_too_few_arguments : Error< 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">; "%0 attribute cannot be applied to sizeless type %1">;
def err_attribute_argument_n_type : Error< def err_attribute_argument_n_type : Error<
"%0 attribute requires parameter %1 to be %select{int or bool|an integer " "%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< def err_attribute_argument_type : Error<
"%0 attribute requires %select{int or bool|an integer " "%0 attribute requires %select{int or bool|an integer "
"constant|a string|an identifier}1">; "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)">; " 1,2,4 or 8 byte type (%0 invalid)">;
def err_atomic_builtin_ext_int_size : Error< def err_atomic_builtin_ext_int_size : Error<
"Atomic memory operand must have a power-of-two size">; "Atomic memory operand must have a power-of-two size">;
def err_atomic_builtin_ext_int_prohibit : Error< def err_atomic_builtin_bit_int_prohibit : Error<
"argument to atomic builtin of type '_ExtInt' is not supported">; "argument to atomic builtin of type '_BitInt' is not supported">;
def err_atomic_op_needs_atomic : Error< def err_atomic_op_needs_atomic : Error<
"address argument to atomic operation must be a pointer to _Atomic " "address argument to atomic operation must be a pointer to _Atomic "
"type (%0 invalid)">; "type (%0 invalid)">;
@ -8374,8 +8388,8 @@ def err_overflow_builtin_must_be_int : Error<
def err_overflow_builtin_must_be_ptr_int : Error< def err_overflow_builtin_must_be_ptr_int : Error<
"result argument to overflow builtin must be a pointer " "result argument to overflow builtin must be a pointer "
"to a non-const integer (%0 invalid)">; "to a non-const integer (%0 invalid)">;
def err_overflow_builtin_ext_int_max_size : Error< def err_overflow_builtin_bit_int_max_size : Error<
"__builtin_mul_overflow does not support signed _ExtInt operands of more " "__builtin_mul_overflow does not support 'signed _BitInt' operands of more "
"than %0 bits">; "than %0 bits">;
def err_atomic_load_store_uses_lib : Error< def err_atomic_load_store_uses_lib : Error<
@ -8626,11 +8640,11 @@ def warn_unused_volatile : Warning<
InGroup<DiagGroup<"unused-volatile-lvalue">>; InGroup<DiagGroup<"unused-volatile-lvalue">>;
def ext_cxx14_attr : Extension< 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< 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< 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< def warn_unused_comparison : Warning<
"%select{equality|inequality|relational|three-way}0 comparison result unused">, "%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; "before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def err_defaulted_comparison_template : Error< def err_defaulted_comparison_template : Error<
"comparison operator template cannot be defaulted">; "comparison operator template cannot be defaulted">;
def err_defaulted_comparison_out_of_class : Error< def err_defaulted_comparison_num_args : Error<
"%sub{select_defaulted_comparison_kind}0 can only be defaulted in a class " "%select{non-member|member}0 %sub{select_defaulted_comparison_kind}1"
"definition">; " comparison operator must have %select{2|1}0 parameters">;
def err_defaulted_comparison_param : Error< def err_defaulted_comparison_param : Error<
"invalid parameter type for defaulted %sub{select_defaulted_comparison_kind}0" "invalid parameter type for defaulted %sub{select_defaulted_comparison_kind}0"
"; found %1, expected %2%select{| or %4}3">; "; 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< def err_defaulted_comparison_param_mismatch : Error<
"parameters for defaulted %sub{select_defaulted_comparison_kind}0 " "parameters for defaulted %sub{select_defaulted_comparison_kind}0 "
"must have the same type%diff{ (found $ vs $)|}1,2">; "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< def err_defaulted_comparison_non_const : Error<
"defaulted member %sub{select_defaulted_comparison_kind}0 must be " "defaulted member %sub{select_defaulted_comparison_kind}0 must be "
"const-qualified">; "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">; "this builtin is only valid on POWER%0 or later CPUs">;
def err_ppc_builtin_requires_vsx : Error< def err_ppc_builtin_requires_vsx : Error<
"this builtin requires VSX to be enabled">; "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< def err_ppc_builtin_requires_abi : Error<
"this builtin requires ABI -mabi=%0">; "this builtin requires ABI -mabi=%0">;
def err_ppc_invalid_use_mma_type : Error< 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< 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">; "%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< 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< 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">; "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< 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 " "a coroutine; include <experimental/coroutine> if your version "
"of libcxx is less than 14.0">; "of libcxx is less than 14.0">;
def warn_deprecated_coroutine_namespace : Warning< 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>; InGroup<DeprecatedExperimentalCoroutine>;
def err_mixed_use_std_and_experimental_namespace_for_coroutine : Error < def err_mixed_use_std_and_experimental_namespace_for_coroutine : Error<
"Found mixed use of std namespace and std::experimental namespace for " "mixed use of std and std::experimental namespaces for "
"coroutine, which is disallowed. The coroutine components in " "coroutine components">;
"std::experimental namespace is deprecated. Please use coroutine components "
"under std namespace.">;
def err_implicit_coroutine_std_nothrow_type_not_found : Error< def err_implicit_coroutine_std_nothrow_type_not_found : Error<
"std::nothrow was not found; include <new> before defining a coroutine which " "std::nothrow was not found; include <new> before defining a coroutine which "
"uses get_return_object_on_allocation_failure()">; "uses get_return_object_on_allocation_failure()">;
@ -11050,8 +11071,6 @@ def err_coroutine_type_missing_specialization : Error<
"specialization %0">; "specialization %0">;
def err_coroutine_promise_incompatible_return_functions : Error< def err_coroutine_promise_incompatible_return_functions : Error<
"the coroutine promise type %0 declares both 'return_value' and 'return_void'">; "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< def note_coroutine_promise_implicit_await_transform_required_here : Note<
"call to 'await_transform' implicitly required by 'co_await' here">; "call to 'await_transform' implicitly required by 'co_await' here">;
def note_coroutine_promise_suspend_implicitly_required : Note< def note_coroutine_promise_suspend_implicitly_required : Note<
@ -11355,8 +11374,10 @@ def err_builtin_launder_invalid_arg : Error<
def err_builtin_invalid_arg_type: Error < def err_builtin_invalid_arg_type: Error <
"%ordinal0 argument must be a " "%ordinal0 argument must be a "
"%select{vector, integer or floating point type|matrix|" "%select{vector, integer or floating point type|matrix|"
"pointer to a valid matrix element type|" "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< def err_builtin_matrix_disabled: Error<
"matrix types extension is disabled. Pass -fenable-matrix to enable it">; "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">, "function template with 'sycl_kernel' attribute must have a 'void' return type">,
InGroup<IgnoredAttributes>; 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">; "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">; "sizes greater than %1 not supported">;
// errors of expect.with.probability // errors of expect.with.probability

View File

@ -153,6 +153,10 @@ class Module {
return Kind == ModuleInterfaceUnit || Kind == PrivateModuleFragment; 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: private:
/// The submodules of this module, indexed by name. /// The submodules of this module, indexed by name.
std::vector<Module *> SubModules; std::vector<Module *> SubModules;

View File

@ -59,7 +59,7 @@ namespace clang {
TST_char32, // C++11 char32_t TST_char32, // C++11 char32_t
TST_int, TST_int,
TST_int128, TST_int128,
TST_extint, // Extended Int types. TST_bitint, // Bit-precise integer types.
TST_half, // OpenCL half, ARM NEON __fp16 TST_half, // OpenCL half, ARM NEON __fp16
TST_Float16, // C11 extension ISO/IEC TS 18661-3 TST_Float16, // C11 extension ISO/IEC TS 18661-3
TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension

View File

@ -582,9 +582,13 @@ class TargetInfo : public virtual TransferrableTargetInfo,
return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128; return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128;
} // FIXME } // 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. /// 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; return false;
} }

View File

@ -300,6 +300,7 @@ KEYWORD(if , KEYALL)
KEYWORD(inline , KEYC99|KEYCXX|KEYGNU) KEYWORD(inline , KEYC99|KEYCXX|KEYGNU)
KEYWORD(int , KEYALL) KEYWORD(int , KEYALL)
KEYWORD(_ExtInt , KEYALL) KEYWORD(_ExtInt , KEYALL)
KEYWORD(_BitInt , KEYALL)
KEYWORD(long , KEYALL) KEYWORD(long , KEYALL)
KEYWORD(register , KEYALL) KEYWORD(register , KEYALL)
KEYWORD(restrict , KEYC99) KEYWORD(restrict , KEYC99)

View File

@ -75,6 +75,7 @@ def DependentSizedMatrixType : TypeNode<MatrixType>, AlwaysDependent;
def FunctionType : TypeNode<Type, 1>; def FunctionType : TypeNode<Type, 1>;
def FunctionProtoType : TypeNode<FunctionType>; def FunctionProtoType : TypeNode<FunctionType>;
def FunctionNoProtoType : TypeNode<FunctionType>; def FunctionNoProtoType : TypeNode<FunctionType>;
def UsingType : TypeNode<Type>, NeverCanonical;
def UnresolvedUsingType : TypeNode<Type>, AlwaysDependent; def UnresolvedUsingType : TypeNode<Type>, AlwaysDependent;
def ParenType : TypeNode<Type>, NeverCanonical; def ParenType : TypeNode<Type>, NeverCanonical;
def TypedefType : TypeNode<Type>, NeverCanonical; def TypedefType : TypeNode<Type>, NeverCanonical;
@ -107,5 +108,5 @@ def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType;
def ObjCObjectPointerType : TypeNode<Type>; def ObjCObjectPointerType : TypeNode<Type>;
def PipeType : TypeNode<Type>; def PipeType : TypeNode<Type>;
def AtomicType : TypeNode<Type>; def AtomicType : TypeNode<Type>;
def ExtIntType : TypeNode<Type>; def BitIntType : TypeNode<Type>;
def DependentExtIntType : TypeNode<Type>, AlwaysDependent; def DependentBitIntType : TypeNode<Type>, AlwaysDependent;

View File

@ -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 /// Get bitmasks for which option flags to include and exclude based on
/// the driver mode. /// the driver mode.
std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const; std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const;

View File

@ -204,6 +204,10 @@ class Command {
/// from the parent process will be used. /// from the parent process will be used.
virtual void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment); 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 char *getExecutable() const { return Executable; }
const llvm::opt::ArgStringList &getArguments() const { return Arguments; } const llvm::opt::ArgStringList &getArguments() const { return Arguments; }

View File

@ -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 " BothFlags<[], " that single precision floating-point divide and sqrt used in "
"the program source are correctly rounded (HIP device compilation only)">>, "the program source are correctly rounded (HIP device compilation only)">>,
ShouldParseIf<hip.KeyPath>; 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", defm gpu_allow_device_init : BoolFOption<"gpu-allow-device-init",
LangOpts<"GPUAllowDeviceInit">, DefaultFalse, LangOpts<"GPUAllowDeviceInit">, DefaultFalse,
PosFlag<SetTrue, [CC1Option], "Allow">, NegFlag<SetFalse, [], "Don't allow">, 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">, NegFlag<SetFalse, [CC1Option], "Disable generation of linker directives for automatic library linking">,
PosFlag<SetTrue>>; 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 // C++ Coroutines TS
defm coroutines_ts : BoolFOption<"coroutines-ts", defm coroutines_ts : BoolFOption<"coroutines-ts",
LangOpts<"Coroutines">, Default<cpp20.KeyPath>, 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]>, def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, FlangOption, FC1Option]>,
HelpText<"Parse OpenMP pragmas and generate parallel code.">; HelpText<"Parse OpenMP pragmas and generate parallel code.">;
def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[NoArgumentUnused]>; 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", defm openmp_extensions: BoolFOption<"openmp-extensions",
LangOpts<"OpenMPExtensions">, DefaultTrue, LangOpts<"OpenMPExtensions">, DefaultTrue,
PosFlag<SetTrue, [CC1Option, NoArgumentUnused], PosFlag<SetTrue, [CC1Option, NoArgumentUnused],
@ -2433,16 +2444,16 @@ def fopenmp_target_debug : Flag<["-"], "fopenmp-target-debug">, Group<f_Group>,
HelpText<"Enable debugging in the OpenMP offloading device RTL">; HelpText<"Enable debugging in the OpenMP offloading device RTL">;
def fno_openmp_target_debug : Flag<["-"], "fno-openmp-target-debug">, Group<f_Group>, Flags<[NoArgumentUnused]>; def fno_openmp_target_debug : Flag<["-"], "fno-openmp-target-debug">, Group<f_Group>, Flags<[NoArgumentUnused]>;
def fopenmp_target_debug_EQ : Joined<["-"], "fopenmp-target-debug=">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; def fopenmp_target_debug_EQ : Joined<["-"], "fopenmp-target-debug=">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
def fopenmp_assume_teams_oversubscription : Flag<["-"], "fopenmp-assume-teams-oversubscription">, def fopenmp_assume_teams_oversubscription : Flag<["-"], "fopenmp-assume-teams-oversubscription">,
Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
def fopenmp_assume_threads_oversubscription : Flag<["-"], "fopenmp-assume-threads-oversubscription">, def fopenmp_assume_threads_oversubscription : Flag<["-"], "fopenmp-assume-threads-oversubscription">,
Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
def fno_openmp_assume_teams_oversubscription : Flag<["-"], "fno-openmp-assume-teams-oversubscription">, def fno_openmp_assume_teams_oversubscription : Flag<["-"], "fno-openmp-assume-teams-oversubscription">,
Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
def fno_openmp_assume_threads_oversubscription : Flag<["-"], "fno-openmp-assume-threads-oversubscription">, def fno_openmp_assume_threads_oversubscription : Flag<["-"], "fno-openmp-assume-threads-oversubscription">,
Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
defm openmp_target_new_runtime: BoolFOption<"openmp-target-new-runtime", 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">, PosFlag<SetTrue, [CC1Option], "Use the new bitcode library for OpenMP offloading">,
NegFlag<SetFalse>>; NegFlag<SetFalse>>;
defm openmp_optimistic_collapse : BoolFOption<"openmp-optimistic-collapse", 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">, def mmark_bti_property : Flag<["-"], "mmark-bti-property">,
Group<m_aarch64_Features_Group>, Group<m_aarch64_Features_Group>,
HelpText<"Add .note.gnu.property with BTI to assembly files (AArch64 only)">; 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 foreach i = {1-31} in
def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_Group>, def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_Group>,
HelpText<"Reserve the x"#i#" register (AArch64/RISC-V only)">; 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=">, def mvscale_min_EQ : Joined<["-"], "mvscale-min=">,
Group<m_aarch64_Features_Group>, Flags<[NoXarchOption,CC1Option]>, Group<m_aarch64_Features_Group>, Flags<[NoXarchOption,CC1Option]>,
HelpText<"Specify the vscale minimum. Defaults to the" HelpText<"Specify the vscale minimum. Defaults to \"1\". (AArch64 only)">,
" vector length agnostic value of \"0\". (AArch64 only)">,
MarshallingInfoInt<LangOpts<"VScaleMin">>; MarshallingInfoInt<LangOpts<"VScaleMin">>;
def mvscale_max_EQ : Joined<["-"], "mvscale-max=">, def mvscale_max_EQ : Joined<["-"], "mvscale-max=">,
Group<m_aarch64_Features_Group>, Flags<[NoXarchOption,CC1Option]>, Group<m_aarch64_Features_Group>, Flags<[NoXarchOption,CC1Option]>,
@ -3759,6 +3774,8 @@ def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option, CoreOption]>,
MarshallingInfoNegativeFlag<HeaderSearchOpts<"UseBuiltinIncludes">>; MarshallingInfoNegativeFlag<HeaderSearchOpts<"UseBuiltinIncludes">>;
def nogpuinc : Flag<["-"], "nogpuinc">, HelpText<"Do not add include paths for CUDA/HIP and" def nogpuinc : Flag<["-"], "nogpuinc">, HelpText<"Do not add include paths for CUDA/HIP and"
" do not include the default CUDA/HIP wrapper headers">; " 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 : Flag<["-"], "nocudainc">, Alias<nogpuinc>;
def nogpulib : Flag<["-"], "nogpulib">, def nogpulib : Flag<["-"], "nogpulib">,
HelpText<"Do not link device library for CUDA/HIP device compilation">; 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]>, CC1Option, CC1AsOption, FC1Option, FlangOption]>,
HelpText<"Write output to <file>">, MetaVarName<"<file>">, HelpText<"Write output to <file>">, MetaVarName<"<file>">,
MarshallingInfoString<FrontendOpts<"OutputFile">>; 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 pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">;
def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>; def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>;
def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group<pedantic_Group>, Flags<[CC1Option]>, 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"]>; Alias<mcpu_EQ>, AliasArgs<["hexagonv67t"]>;
def mv68 : Flag<["-"], "mv68">, Group<m_hexagon_Features_Group>, def mv68 : Flag<["-"], "mv68">, Group<m_hexagon_Features_Group>,
Alias<mcpu_EQ>, AliasArgs<["hexagonv68"]>; 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>, def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_HVX_Group>,
HelpText<"Enable Hexagon Vector eXtensions">; HelpText<"Enable Hexagon Vector eXtensions">;
def mhexagon_hvx_EQ : Joined<["-"], "mhvx=">, 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=">, def mhexagon_hvx_length_EQ : Joined<["-"], "mhvx-length=">,
Group<m_hexagon_Features_HVX_Group>, HelpText<"Set Hexagon Vector Length">, Group<m_hexagon_Features_HVX_Group>, HelpText<"Set Hexagon Vector Length">,
Values<"64B,128B">; 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">, def ffixed_r19: Flag<["-"], "ffixed-r19">,
HelpText<"Reserve register r19 (Hexagon only)">; HelpText<"Reserve register r19 (Hexagon only)">;
def mmemops : Flag<["-"], "mmemops">, Group<m_hexagon_Features_Group>, def mmemops : Flag<["-"], "mmemops">, Group<m_hexagon_Features_Group>,

View File

@ -52,6 +52,7 @@ class Tool {
const ToolChain &getToolChain() const { return TheToolChain; } const ToolChain &getToolChain() const { return TheToolChain; }
virtual bool hasIntegratedAssembler() const { return false; } virtual bool hasIntegratedAssembler() const { return false; }
virtual bool hasIntegratedBackend() const { return true; }
virtual bool canEmitIR() const { return false; } virtual bool canEmitIR() const { return false; }
virtual bool hasIntegratedCPP() const = 0; virtual bool hasIntegratedCPP() const = 0;
virtual bool isLinkJob() const { return false; } virtual bool isLinkJob() const { return false; }

View File

@ -348,10 +348,7 @@ class ToolChain {
/// is LLD. If it's set, it can be assumed that the linker is LLD built /// 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 /// at the same revision as clang, and clang can make assumptions about
/// LLD's supported flags, error output, etc. /// LLD's supported flags, error output, etc.
/// If LinkerIsLLDDarwinNew is non-nullptr, it's set if the linker is std::string GetLinkerPath(bool *LinkerIsLLD = nullptr) const;
/// the new version in lld/MachO.
std::string GetLinkerPath(bool *LinkerIsLLD = nullptr,
bool *LinkerIsLLDDarwinNew = nullptr) const;
/// Returns the linker path for emitting a static library. /// Returns the linker path for emitting a static library.
std::string GetStaticLibToolPath() const; std::string GetStaticLibToolPath() const;
@ -387,6 +384,9 @@ class ToolChain {
/// Check if the toolchain should use the integrated assembler. /// Check if the toolchain should use the integrated assembler.
virtual bool useIntegratedAs() const; 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 /// Check if the toolchain should use AsmParser to parse inlineAsm when
/// integrated assembler is not default. /// integrated assembler is not default.
virtual bool parseInlineAsmUsingAsmParser() const { return false; } virtual bool parseInlineAsmUsingAsmParser() const { return false; }

View File

@ -2669,6 +2669,7 @@ struct FormatStyle {
bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; } bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; }
bool isCSharp() const { return Language == LK_CSharp; } bool isCSharp() const { return Language == LK_CSharp; }
bool isJson() const { return Language == LK_Json; } bool isJson() const { return Language == LK_Json; }
bool isJavaScript() const { return Language == LK_JavaScript; }
/// Language, this format style is targeted at. /// Language, this format style is targeted at.
/// \version 3.5 /// \version 3.5

View File

@ -538,8 +538,11 @@ class ModuleMap {
/// ///
/// We model the global module fragment as a submodule of the module /// We model the global module fragment as a submodule of the module
/// interface unit. Unfortunately, we can't create the module interface /// 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. /// unit's Module until later, because we don't know what it will be called
Module *createGlobalModuleFragmentForModuleUnit(SourceLocation Loc); /// 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. /// Create a global module fragment for a C++ module interface unit.
Module *createPrivateModuleFragmentForInterfaceUnit(Module *Parent, Module *createPrivateModuleFragmentForInterfaceUnit(Module *Parent,

View File

@ -2564,6 +2564,10 @@ class Parser : public CodeCompletionHandler {
/// full validation of the syntactic structure of attributes. /// full validation of the syntactic structure of attributes.
bool TrySkipAttributes(); 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: public:
TypeResult TypeResult
ParseTypeName(SourceRange *Range = nullptr, ParseTypeName(SourceRange *Range = nullptr,

View File

@ -266,7 +266,7 @@ class DeclSpec {
static const TST TST_char32 = clang::TST_char32; static const TST TST_char32 = clang::TST_char32;
static const TST TST_int = clang::TST_int; static const TST TST_int = clang::TST_int;
static const TST TST_int128 = clang::TST_int128; 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_half = clang::TST_half;
static const TST TST_BFloat16 = clang::TST_BFloat16; static const TST TST_BFloat16 = clang::TST_BFloat16;
static const TST TST_float = clang::TST_float; static const TST TST_float = clang::TST_float;
@ -404,7 +404,7 @@ class DeclSpec {
T == TST_underlyingType || T == TST_atomic); T == TST_underlyingType || T == TST_atomic);
} }
static bool isExprRep(TST T) { 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) { static bool isTemplateIdRep(TST T) {
return (T == TST_auto || T == TST_decltype_auto); return (T == TST_auto || T == TST_decltype_auto);
@ -703,7 +703,7 @@ class DeclSpec {
bool SetTypePipe(bool isPipe, SourceLocation Loc, bool SetTypePipe(bool isPipe, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID, const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy); const PrintingPolicy &Policy);
bool SetExtIntType(SourceLocation KWLoc, Expr *BitWidth, bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth,
const char *&PrevSpec, unsigned &DiagID, const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy); const PrintingPolicy &Policy);
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec,

View File

@ -1097,6 +1097,7 @@ enum AttributeArgumentNType {
AANT_ArgumentString, AANT_ArgumentString,
AANT_ArgumentIdentifier, AANT_ArgumentIdentifier,
AANT_ArgumentConstantExpr, AANT_ArgumentConstantExpr,
AANT_ArgumentBuiltinFunction,
}; };
/// These constants match the enumerated choices of /// These constants match the enumerated choices of

View File

@ -1324,12 +1324,15 @@ class Sema final {
bool isImmediateFunctionContext() const { bool isImmediateFunctionContext() const {
return Context == ExpressionEvaluationContext::ImmediateFunctionContext || return Context == ExpressionEvaluationContext::ImmediateFunctionContext ||
InImmediateFunctionContext; (Context == ExpressionEvaluationContext::DiscardedStatement &&
InImmediateFunctionContext);
} }
bool isDiscardedStatementContext() const { bool isDiscardedStatementContext() const {
return Context == ExpressionEvaluationContext::DiscardedStatement || return Context == ExpressionEvaluationContext::DiscardedStatement ||
InDiscardedStatement; (Context ==
ExpressionEvaluationContext::ImmediateFunctionContext &&
InDiscardedStatement);
} }
}; };
@ -2043,7 +2046,7 @@ class Sema final {
SourceLocation Loc); SourceLocation Loc);
QualType BuildWritePipeType(QualType T, QualType BuildWritePipeType(QualType T,
SourceLocation Loc); 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 *GetTypeForDeclarator(Declarator &D, Scope *S);
TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy); TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
@ -2219,6 +2222,17 @@ class Sema final {
return ModuleScopes.empty() ? nullptr : ModuleScopes.back().Module; 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; VisibleModuleSet VisibleModules;
public: public:
@ -11176,6 +11190,9 @@ class Sema final {
/// Called on well-formed 'capture' clause. /// Called on well-formed 'capture' clause.
OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc, OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc,
SourceLocation EndLoc); SourceLocation EndLoc);
/// Called on well-formed 'compare' clause.
OMPClause *ActOnOpenMPCompareClause(SourceLocation StartLoc,
SourceLocation EndLoc);
/// Called on well-formed 'seq_cst' clause. /// Called on well-formed 'seq_cst' clause.
OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc, OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
SourceLocation EndLoc); SourceLocation EndLoc);
@ -12769,8 +12786,8 @@ class Sema final {
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc); bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc);
bool SemaBuiltinElementwiseMath(CallExpr *TheCall); bool SemaBuiltinElementwiseMath(CallExpr *TheCall);
bool SemaBuiltinElementwiseMathOneArg(CallExpr *TheCall); bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall);
bool SemaBuiltinReduceMath(CallExpr *TheCall); bool PrepareBuiltinReduceMathOneArgCall(CallExpr *TheCall);
// Matrix builtin handling. // Matrix builtin handling.
ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall, ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall,

View File

@ -58,9 +58,10 @@ TYPE_BIT_CODE(DependentSizedExtVector, DEPENDENT_SIZED_EXT_VECTOR, 46)
TYPE_BIT_CODE(DependentAddressSpace, DEPENDENT_ADDRESS_SPACE, 47) TYPE_BIT_CODE(DependentAddressSpace, DEPENDENT_ADDRESS_SPACE, 47)
TYPE_BIT_CODE(DependentVector, DEPENDENT_SIZED_VECTOR, 48) TYPE_BIT_CODE(DependentVector, DEPENDENT_SIZED_VECTOR, 48)
TYPE_BIT_CODE(MacroQualified, MACRO_QUALIFIED, 49) TYPE_BIT_CODE(MacroQualified, MACRO_QUALIFIED, 49)
TYPE_BIT_CODE(ExtInt, EXT_INT, 50) TYPE_BIT_CODE(BitInt, BIT_INT, 50)
TYPE_BIT_CODE(DependentExtInt, DEPENDENT_EXT_INT, 51) TYPE_BIT_CODE(DependentBitInt, DEPENDENT_BIT_INT, 51)
TYPE_BIT_CODE(ConstantMatrix, CONSTANT_MATRIX, 52) TYPE_BIT_CODE(ConstantMatrix, CONSTANT_MATRIX, 52)
TYPE_BIT_CODE(DependentSizedMatrix, DEPENDENT_SIZE_MATRIX, 53) TYPE_BIT_CODE(DependentSizedMatrix, DEPENDENT_SIZE_MATRIX, 53)
TYPE_BIT_CODE(Using, USING, 54)
#undef TYPE_BIT_CODE #undef TYPE_BIT_CODE

View File

@ -32,7 +32,7 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
std::string Str; std::string Str;
llvm::raw_string_ostream OS(Str); llvm::raw_string_ostream OS(Str);
S->printPretty(OS, nullptr, PrintingPolicy(ACtx.getLangOpts())); S->printPretty(OS, nullptr, PrintingPolicy(ACtx.getLangOpts()));
return OS.str(); return Str;
} }
bool isThisObject(const SymbolicRegion *R) { bool isThisObject(const SymbolicRegion *R) {
@ -69,7 +69,7 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
std::string Str; std::string Str;
llvm::raw_string_ostream OS(Str); llvm::raw_string_ostream OS(Str);
OS << "concrete memory address '" << I << "'"; OS << "concrete memory address '" << I << "'";
return OS.str(); return Str;
} }
std::string VisitNonLocSymbolVal(nonloc::SymbolVal V) { std::string VisitNonLocSymbolVal(nonloc::SymbolVal V) {
@ -82,7 +82,7 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
llvm::raw_string_ostream OS(Str); llvm::raw_string_ostream OS(Str);
OS << (I.isSigned() ? "signed " : "unsigned ") << I.getBitWidth() OS << (I.isSigned() ? "signed " : "unsigned ") << I.getBitWidth()
<< "-bit integer '" << I << "'"; << "-bit integer '" << I << "'";
return OS.str(); return Str;
} }
std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V) { std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V) {
@ -123,7 +123,7 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
OS << "(" << Visit(S->getLHS()) << ") " OS << "(" << Visit(S->getLHS()) << ") "
<< std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) << " " << std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) << " "
<< S->getRHS(); << S->getRHS();
return OS.str(); return Str;
} }
// TODO: IntSymExpr doesn't appear in practice. // TODO: IntSymExpr doesn't appear in practice.
@ -177,7 +177,7 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
else else
OS << "'" << Visit(R->getIndex()) << "'"; OS << "'" << Visit(R->getIndex()) << "'";
OS << " of " + Visit(R->getSuperRegion()); OS << " of " + Visit(R->getSuperRegion());
return OS.str(); return Str;
} }
std::string VisitNonParamVarRegion(const NonParamVarRegion *R) { std::string VisitNonParamVarRegion(const NonParamVarRegion *R) {

View File

@ -336,6 +336,18 @@ ANALYZER_OPTION(
"might be modeled by the analyzer to never return NULL.", "might be modeled by the analyzer to never return NULL.",
false) 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. // Unsigned analyzer options.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -134,6 +134,9 @@ template <typename T> class CallDescriptionMap {
std::initializer_list<std::pair<CallDescription, T>> &&List) std::initializer_list<std::pair<CallDescription, T>> &&List)
: LinearMap(List) {} : LinearMap(List) {}
template <typename InputIt>
CallDescriptionMap(InputIt First, InputIt Last) : LinearMap(First, Last) {}
~CallDescriptionMap() = default; ~CallDescriptionMap() = default;
// These maps are usually stored once per checker, so let's make sure // 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(const CallDescriptionMap &) = delete;
CallDescriptionMap &operator=(const CallDescription &) = delete; CallDescriptionMap &operator=(const CallDescription &) = delete;
CallDescriptionMap(CallDescriptionMap &&) = default;
CallDescriptionMap &operator=(CallDescriptionMap &&) = default;
LLVM_NODISCARD const T *lookup(const CallEvent &Call) const { LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
// Slow path: linear lookup. // Slow path: linear lookup.
// TODO: Implement some sort of fast path. // TODO: Implement some sort of fast path.

View File

@ -140,6 +140,30 @@ class RangeSet {
/// Complexity: O(N) /// Complexity: O(N)
/// where N = size(Original) /// where N = size(Original)
RangeSet add(RangeSet Original, const llvm::APSInt &Point); 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; } RangeSet getEmptySet() { return &EmptySet; }
@ -224,6 +248,9 @@ class RangeSet {
ContainerType *construct(ContainerType &&From); ContainerType *construct(ContainerType &&From);
RangeSet intersect(const ContainerType &LHS, const ContainerType &RHS); 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 // Many operations include producing new APSInt values and that's why
// we need this factory. // we need this factory.

View File

@ -172,9 +172,9 @@ class StoreManager {
/// dynamic_cast. /// dynamic_cast.
/// - We don't know (base is a symbolic region and we don't have /// - 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). /// enough info to determine if the cast will succeed at run time).
/// The function returns an SVal representing the derived class; it's /// The function returns an optional with SVal representing the derived class
/// valid only if Failed flag is set to false. /// in case of a successful cast and `None` otherwise.
SVal attemptDownCast(SVal Base, QualType DerivedPtrType, bool &Failed); Optional<SVal> evalBaseToDerived(SVal Base, QualType DerivedPtrType);
const ElementRegion *GetElementZeroRegion(const SubRegion *R, QualType T); const ElementRegion *GetElementZeroRegion(const SubRegion *R, QualType T);

View File

@ -73,7 +73,7 @@ struct TestClangConfig {
std::string Result; std::string Result;
llvm::raw_string_ostream OS(Result); llvm::raw_string_ostream OS(Result);
OS << "{ Language=" << Language << ", Target=" << Target << " }"; OS << "{ Language=" << Language << ", Target=" << Target << " }";
return OS.str(); return Result;
} }
friend std::ostream &operator<<(std::ostream &OS, friend std::ostream &operator<<(std::ostream &OS,

View File

@ -26,57 +26,83 @@ namespace dependencies {
/// the dependency scanning filesystem. /// the dependency scanning filesystem.
/// ///
/// It represents one of the following: /// It represents one of the following:
/// - an opened source file with minimized contents and a stat value. /// - opened file with original contents and a stat value,
/// - an opened source file with original contents and a stat value. /// - opened file with original contents, minimized contents and a stat value,
/// - a directory entry with its stat value. /// - directory entry with its stat value,
/// - an error value to represent a file system error. /// - filesystem error,
/// - a placeholder with an invalid stat indicating a not yet initialized entry. /// - uninitialized entry with unknown status.
class CachedFileSystemEntry { class CachedFileSystemEntry {
public: public:
/// Default constructor creates an entry with an invalid stat. /// Creates an uninitialized entry.
CachedFileSystemEntry() : MaybeStat(llvm::vfs::Status()) {} 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 /// Initialize the entry as file with minimized or original contents.
/// original contents.
/// ///
/// The filesystem opens the file even for `stat` calls open to avoid the /// 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 /// 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 /// mismatching size of the file.
/// read and copied into memory to ensure that it's not memory mapped to avoid llvm::ErrorOr<llvm::vfs::Status> initFile(StringRef Filename,
/// running out of file descriptors. llvm::vfs::FileSystem &FS);
static CachedFileSystemEntry createFileEntry(StringRef Filename,
llvm::vfs::FileSystem &FS,
bool Minimize = true);
/// Create an entry that represents a directory on the filesystem. /// Minimize contents of the file.
static CachedFileSystemEntry createDirectoryEntry(llvm::vfs::Status &&Stat); void minimizeFile();
/// \returns True if the entry is valid. /// \returns True if the entry is initialized.
bool isValid() const { return !MaybeStat || MaybeStat->isStatusKnown(); } bool isInitialized() const {
return !MaybeStat || MaybeStat->isStatusKnown();
}
/// \returns True if the current entry points to a directory. /// \returns True if the current entry points to a directory.
bool isDirectory() const { return MaybeStat && MaybeStat->isDirectory(); } bool isDirectory() const { return MaybeStat && MaybeStat->isDirectory(); }
/// \returns The error or the file's contents. /// \returns The error or the file's original contents.
llvm::ErrorOr<StringRef> getContents() const { llvm::ErrorOr<StringRef> getOriginalContents() const {
if (!MaybeStat) if (!MaybeStat)
return MaybeStat.getError(); return MaybeStat.getError();
assert(!MaybeStat->isDirectory() && "not a file"); assert(!MaybeStat->isDirectory() && "not a file");
assert(isValid() && "not initialized"); assert(isInitialized() && "not initialized");
return Contents.str(); 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. /// \returns The error or the status of the entry.
llvm::ErrorOr<llvm::vfs::Status> getStatus() const { llvm::ErrorOr<llvm::vfs::Status> getStatus() const {
assert(isValid() && "not initialized"); assert(isInitialized() && "not initialized");
return MaybeStat; return MaybeStat;
} }
/// \returns the name of the file. /// \returns the name of the file.
StringRef getName() const { StringRef getName() const {
assert(isValid() && "not initialized"); assert(isInitialized() && "not initialized");
return MaybeStat->getName(); return MaybeStat->getName();
} }
@ -86,19 +112,16 @@ class CachedFileSystemEntry {
return PPSkippedRangeMapping; return PPSkippedRangeMapping;
} }
CachedFileSystemEntry(CachedFileSystemEntry &&) = default;
CachedFileSystemEntry &operator=(CachedFileSystemEntry &&) = default;
CachedFileSystemEntry(const CachedFileSystemEntry &) = delete;
CachedFileSystemEntry &operator=(const CachedFileSystemEntry &) = delete;
private: private:
llvm::ErrorOr<llvm::vfs::Status> MaybeStat; llvm::ErrorOr<llvm::vfs::Status> MaybeStat;
// Store the contents in a small string to allow a std::unique_ptr<llvm::MemoryBuffer> OriginalContents;
// move from the small string for the minimized contents.
// Note: small size of 1 allows us to store an empty string with an implicit /// Owning storage for the minimized file contents.
// null terminator without any allocations. std::unique_ptr<llvm::MemoryBuffer> MinimizedContentsStorage;
llvm::SmallString<1> Contents; /// Atomic view of the minimized file contents.
/// This prevents data races when multiple threads call `needsMinimization`.
std::atomic<llvm::MemoryBuffer *> MinimizedContentsAccess;
PreprocessorSkippedRangeMapping PPSkippedRangeMapping; PreprocessorSkippedRangeMapping PPSkippedRangeMapping;
}; };
@ -115,61 +138,70 @@ class DependencyScanningFilesystemSharedCache {
CachedFileSystemEntry Value; CachedFileSystemEntry Value;
}; };
DependencyScanningFilesystemSharedCache();
/// Returns a cache entry for the corresponding key. /// 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 /// A new cache entry is created if the key is not in the cache. This is a
/// thread safe call. /// thread safe call.
SharedFileSystemEntry &get(StringRef Key, bool Minimized); SharedFileSystemEntry &get(StringRef Key);
private: private:
class SingleCache { struct CacheShard {
public: std::mutex CacheLock;
SingleCache(); llvm::StringMap<SharedFileSystemEntry, llvm::BumpPtrAllocator> Cache;
SharedFileSystemEntry &get(StringRef Key);
private:
struct CacheShard {
std::mutex CacheLock;
llvm::StringMap<SharedFileSystemEntry, llvm::BumpPtrAllocator> Cache;
};
std::unique_ptr<CacheShard[]> CacheShards;
unsigned NumShards;
}; };
std::unique_ptr<CacheShard[]> CacheShards;
SingleCache CacheMinimized; unsigned NumShards;
SingleCache CacheOriginal;
}; };
/// This class is a local cache, that caches the 'stat' and 'open' calls to the /// 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 /// underlying real file system. It distinguishes between minimized and original
/// files. /// files.
class DependencyScanningFilesystemLocalCache { class DependencyScanningFilesystemLocalCache {
private: llvm::StringMap<const CachedFileSystemEntry *, llvm::BumpPtrAllocator> Cache;
using SingleCache =
llvm::StringMap<const CachedFileSystemEntry *, llvm::BumpPtrAllocator>;
SingleCache CacheMinimized;
SingleCache CacheOriginal;
SingleCache &selectCache(bool Minimized) {
return Minimized ? CacheMinimized : CacheOriginal;
}
public: public:
void setCachedEntry(StringRef Filename, bool Minimized, const CachedFileSystemEntry *getCachedEntry(StringRef Filename) {
const CachedFileSystemEntry *Entry) { return Cache[Filename];
SingleCache &Cache = selectCache(Minimized); }
bool IsInserted = Cache.try_emplace(Filename, Entry).second; };
(void)IsInserted;
assert(IsInserted && "local cache is updated more than once"); /// 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 isDirectory() const { return Entry.isDirectory(); }
bool Minimized) {
SingleCache &Cache = selectCache(Minimized); StringRef getName() const { return Entry.getName(); }
auto It = Cache.find(Filename);
return It == Cache.end() ? nullptr : It->getValue(); 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. /// Check whether the file should be minimized.
bool shouldMinimize(StringRef Filename); bool shouldMinimize(StringRef Filename);
llvm::ErrorOr<const CachedFileSystemEntry *> llvm::ErrorOr<EntryRef> getOrCreateFileSystemEntry(StringRef Filename);
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);
/// The global cache shared between worker threads. /// The global cache shared between worker threads.
DependencyScanningFilesystemSharedCache &SharedCache; DependencyScanningFilesystemSharedCache &SharedCache;
/// The local cache is used by the worker thread to cache file system queries /// The local cache is used by the worker thread to cache file system queries
/// locally instead of querying the global cache every time. /// locally instead of querying the global cache every time.
DependencyScanningFilesystemLocalCache Cache; DependencyScanningFilesystemLocalCache LocalCache;
/// The optional mapping structure which records information about the /// The optional mapping structure which records information about the
/// excluded conditional directive skip mappings that are used by the /// excluded conditional directive skip mappings that are used by the
/// currently active preprocessor. /// currently active preprocessor.

View File

@ -106,7 +106,7 @@ struct IncludeStyle {
/// Priority: 2 /// Priority: 2
/// SortPriority: 2 /// SortPriority: 2
/// CaseSensitive: true /// CaseSensitive: true
/// - Regex: '^(<|"(gtest|gmock|isl|json)/)' /// - Regex: '^((<|")(gtest|gmock|isl|json)/)'
/// Priority: 3 /// Priority: 3
/// - Regex: '<[[:alnum:].]+>' /// - Regex: '<[[:alnum:].]+>'
/// Priority: 4 /// Priority: 4

View File

@ -34,6 +34,8 @@ module Clang_Basic {
textual header "Basic/AArch64SVEACLETypes.def" textual header "Basic/AArch64SVEACLETypes.def"
textual header "Basic/BuiltinsAArch64.def" textual header "Basic/BuiltinsAArch64.def"
textual header "Basic/BuiltinsAMDGPU.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/BuiltinsARM.def"
textual header "Basic/BuiltinsBPF.def" textual header "Basic/BuiltinsBPF.def"
textual header "Basic/Builtins.def" textual header "Basic/Builtins.def"

View File

@ -162,9 +162,7 @@ static bool HasARCRuntime(CompilerInvocation &origCI) {
return triple.getOSMajorVersion() >= 11; return triple.getOSMajorVersion() >= 11;
if (triple.getOS() == llvm::Triple::MacOSX) { if (triple.getOS() == llvm::Triple::MacOSX) {
unsigned Major, Minor, Micro; return triple.getOSVersion() >= VersionTuple(10, 7);
triple.getOSVersion(Major, Minor, Micro);
return Major > 10 || (Major == 10 && Minor >= 7);
} }
return false; return false;

View File

@ -2286,8 +2286,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Align = toBits(Layout.getAlignment()); Align = toBits(Layout.getAlignment());
break; break;
} }
case Type::ExtInt: { case Type::BitInt: {
const auto *EIT = cast<ExtIntType>(T); const auto *EIT = cast<BitIntType>(T);
Align = Align =
std::min(static_cast<unsigned>(std::max( std::min(static_cast<unsigned>(std::max(
getCharWidth(), llvm::PowerOf2Ceil(EIT->getNumBits()))), getCharWidth(), llvm::PowerOf2Ceil(EIT->getNumBits()))),
@ -2349,6 +2349,9 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case Type::ObjCTypeParam: case Type::ObjCTypeParam:
return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr()); return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr());
case Type::Using:
return getTypeInfo(cast<UsingType>(T)->desugar().getTypePtr());
case Type::Typedef: { case Type::Typedef: {
const TypedefNameDecl *Typedef = cast<TypedefType>(T)->getDecl(); const TypedefNameDecl *Typedef = cast<TypedefType>(T)->getDecl();
TypeInfo Info = getTypeInfo(Typedef->getUnderlyingType().getTypePtr()); TypeInfo Info = getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
@ -3569,8 +3572,8 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
case Type::Auto: case Type::Auto:
case Type::DeducedTemplateSpecialization: case Type::DeducedTemplateSpecialization:
case Type::PackExpansion: case Type::PackExpansion:
case Type::ExtInt: case Type::BitInt:
case Type::DependentExtInt: case Type::DependentBitInt:
llvm_unreachable("type should never be variably-modified"); llvm_unreachable("type should never be variably-modified");
// These types can be variably-modified but should never need to // 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); return getPipeType(T, false);
} }
QualType ASTContext::getExtIntType(bool IsUnsigned, unsigned NumBits) const { QualType ASTContext::getBitIntType(bool IsUnsigned, unsigned NumBits) const {
llvm::FoldingSetNodeID ID; llvm::FoldingSetNodeID ID;
ExtIntType::Profile(ID, IsUnsigned, NumBits); BitIntType::Profile(ID, IsUnsigned, NumBits);
void *InsertPos = nullptr; void *InsertPos = nullptr;
if (ExtIntType *EIT = ExtIntTypes.FindNodeOrInsertPos(ID, InsertPos)) if (BitIntType *EIT = BitIntTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(EIT, 0); return QualType(EIT, 0);
auto *New = new (*this, TypeAlignment) ExtIntType(IsUnsigned, NumBits); auto *New = new (*this, TypeAlignment) BitIntType(IsUnsigned, NumBits);
ExtIntTypes.InsertNode(New, InsertPos); BitIntTypes.InsertNode(New, InsertPos);
Types.push_back(New); Types.push_back(New);
return QualType(New, 0); return QualType(New, 0);
} }
QualType ASTContext::getDependentExtIntType(bool IsUnsigned, QualType ASTContext::getDependentBitIntType(bool IsUnsigned,
Expr *NumBitsExpr) const { Expr *NumBitsExpr) const {
assert(NumBitsExpr->isInstantiationDependent() && "Only good for dependent"); assert(NumBitsExpr->isInstantiationDependent() && "Only good for dependent");
llvm::FoldingSetNodeID ID; llvm::FoldingSetNodeID ID;
DependentExtIntType::Profile(ID, *this, IsUnsigned, NumBitsExpr); DependentBitIntType::Profile(ID, *this, IsUnsigned, NumBitsExpr);
void *InsertPos = nullptr; void *InsertPos = nullptr;
if (DependentExtIntType *Existing = if (DependentBitIntType *Existing =
DependentExtIntTypes.FindNodeOrInsertPos(ID, InsertPos)) DependentBitIntTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(Existing, 0); return QualType(Existing, 0);
auto *New = new (*this, TypeAlignment) auto *New = new (*this, TypeAlignment)
DependentExtIntType(*this, IsUnsigned, NumBitsExpr); DependentBitIntType(*this, IsUnsigned, NumBitsExpr);
DependentExtIntTypes.InsertNode(New, InsertPos); DependentBitIntTypes.InsertNode(New, InsertPos);
Types.push_back(New); Types.push_back(New);
return QualType(New, 0); return QualType(New, 0);
@ -4568,9 +4571,7 @@ QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const {
assert(Enum->isFirstDecl() && "enum has previous declaration"); assert(Enum->isFirstDecl() && "enum has previous declaration");
return getEnumType(Enum); return getEnumType(Enum);
} else if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) { } else if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
Type *newType = new (*this, TypeAlignment) UnresolvedUsingType(Using); return getUnresolvedUsingType(Using);
Decl->TypeForDecl = newType;
Types.push_back(newType);
} else } else
llvm_unreachable("TypeDecl without a type?"); llvm_unreachable("TypeDecl without a type?");
@ -4593,6 +4594,27 @@ QualType ASTContext::getTypedefType(const TypedefNameDecl *Decl,
return QualType(newType, 0); 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 { QualType ASTContext::getRecordType(const RecordDecl *Decl) const {
if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
@ -4619,6 +4641,22 @@ QualType ASTContext::getEnumType(const EnumDecl *Decl) const {
return QualType(newType, 0); 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 ASTContext::getAttributedType(attr::Kind attrKind,
QualType modifiedType, QualType modifiedType,
QualType equivalentType) { 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 // Results in this 'losing' to any type of the same size, but winning if
// larger. // larger.
if (const auto *EIT = dyn_cast<ExtIntType>(T)) if (const auto *EIT = dyn_cast<BitIntType>(T))
return 0 + (EIT->getNumBits() << 3); return 0 + (EIT->getNumBits() << 3);
switch (cast<BuiltinType>(T)->getKind()) { switch (cast<BuiltinType>(T)->getKind()) {
@ -7885,7 +7923,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
return; return;
case Type::Pipe: case Type::Pipe:
case Type::ExtInt: case Type::BitInt:
#define ABSTRACT_TYPE(KIND, BASE) #define ABSTRACT_TYPE(KIND, BASE)
#define TYPE(KIND, BASE) #define TYPE(KIND, BASE)
#define DEPENDENT_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. // Remove any implied protocols from the list of inherited protocols.
if (!ImpliedProtocols.empty()) { if (!ImpliedProtocols.empty()) {
llvm::erase_if(IntersectionSet, [&](ObjCProtocolDecl *proto) -> bool { 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 && assert(LHS != RHS &&
"Equivalent pipe types should have already been handled!"); "Equivalent pipe types should have already been handled!");
return {}; return {};
case Type::ExtInt: { case Type::BitInt: {
// Merge two ext-int types, while trying to preserve typedef info. // Merge two bit-precise int types, while trying to preserve typedef info.
bool LHSUnsigned = LHS->castAs<ExtIntType>()->isUnsigned(); bool LHSUnsigned = LHS->castAs<BitIntType>()->isUnsigned();
bool RHSUnsigned = RHS->castAs<ExtIntType>()->isUnsigned(); bool RHSUnsigned = RHS->castAs<BitIntType>()->isUnsigned();
unsigned LHSBits = LHS->castAs<ExtIntType>()->getNumBits(); unsigned LHSBits = LHS->castAs<BitIntType>()->getNumBits();
unsigned RHSBits = RHS->castAs<ExtIntType>()->getNumBits(); unsigned RHSBits = RHS->castAs<BitIntType>()->getNumBits();
// Like unsigned/int, shouldn't have a type if they don't match. // Like unsigned/int, shouldn't have a type if they don't match.
if (LHSUnsigned != RHSUnsigned) if (LHSUnsigned != RHSUnsigned)
@ -10254,7 +10292,7 @@ unsigned ASTContext::getIntWidth(QualType T) const {
T = ET->getDecl()->getIntegerType(); T = ET->getDecl()->getIntegerType();
if (T->isBooleanType()) if (T->isBooleanType())
return 1; return 1;
if(const auto *EIT = T->getAs<ExtIntType>()) if (const auto *EIT = T->getAs<BitIntType>())
return EIT->getNumBits(); return EIT->getNumBits();
// For builtin types, just use the standard type sizing method // For builtin types, just use the standard type sizing method
return (unsigned)getTypeSize(T); return (unsigned)getTypeSize(T);
@ -10269,9 +10307,9 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()), return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()),
VTy->getNumElements(), VTy->getVectorKind()); VTy->getNumElements(), VTy->getVectorKind());
// For _ExtInt, return an unsigned _ExtInt with same width. // For _BitInt, return an unsigned _BitInt with same width.
if (const auto *EITy = T->getAs<ExtIntType>()) if (const auto *EITy = T->getAs<BitIntType>())
return getExtIntType(/*IsUnsigned=*/true, EITy->getNumBits()); return getBitIntType(/*IsUnsigned=*/true, EITy->getNumBits());
// For enums, get the underlying integer type of the enum, and let the general // For enums, get the underlying integer type of the enum, and let the general
// integer type signchanging code handle it. // integer type signchanging code handle it.
@ -10337,9 +10375,9 @@ QualType ASTContext::getCorrespondingSignedType(QualType T) const {
return getVectorType(getCorrespondingSignedType(VTy->getElementType()), return getVectorType(getCorrespondingSignedType(VTy->getElementType()),
VTy->getNumElements(), VTy->getVectorKind()); VTy->getNumElements(), VTy->getVectorKind());
// For _ExtInt, return a signed _ExtInt with same width. // For _BitInt, return a signed _BitInt with same width.
if (const auto *EITy = T->getAs<ExtIntType>()) if (const auto *EITy = T->getAs<BitIntType>())
return getExtIntType(/*IsUnsigned=*/false, EITy->getNumBits()); return getBitIntType(/*IsUnsigned=*/false, EITy->getNumBits());
// For enums, get the underlying integer type of the enum, and let the general // For enums, get the underlying integer type of the enum, and let the general
// integer type signchanging code handle it. // integer type signchanging code handle it.

View File

@ -26,7 +26,8 @@ using namespace clang;
// Returns a desugared version of the QualType, and marks ShouldAKA as true // Returns a desugared version of the QualType, and marks ShouldAKA as true
// whenever we remove significant sugar from the type. // 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; QualifierCollector QC;
while (true) { while (true) {
@ -37,6 +38,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
QT = ET->desugar(); QT = ET->desugar();
continue; continue;
} }
// ... or a using type ...
if (const UsingType *UT = dyn_cast<UsingType>(Ty)) {
QT = UT->desugar();
continue;
}
// ... or a paren type ... // ... or a paren type ...
if (const ParenType *PT = dyn_cast<ParenType>(Ty)) { if (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
QT = PT->desugar(); QT = PT->desugar();
@ -76,7 +82,7 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
if (const FunctionType *FT = dyn_cast<FunctionType>(Ty)) { if (const FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
bool DesugarReturn = false; bool DesugarReturn = false;
QualType SugarRT = FT->getReturnType(); QualType SugarRT = FT->getReturnType();
QualType RT = Desugar(Context, SugarRT, DesugarReturn); QualType RT = desugarForDiagnostic(Context, SugarRT, DesugarReturn);
if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) { if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) {
RT = Context.getAttributedType( RT = Context.getAttributedType(
AttributedType::getNullabilityAttrKind(*nullability), RT, RT); 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); const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT);
if (FPT) { if (FPT) {
for (QualType SugarPT : FPT->param_types()) { for (QualType SugarPT : FPT->param_types()) {
QualType PT = Desugar(Context, SugarPT, DesugarArgument); QualType PT = desugarForDiagnostic(Context, SugarPT, DesugarArgument);
if (auto nullability = if (auto nullability =
AttributedType::stripOuterNullability(SugarPT)) { AttributedType::stripOuterNullability(SugarPT)) {
PT = Context.getAttributedType( 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) { for (unsigned I = 0, N = TST->getNumArgs(); I != N; ++I) {
const TemplateArgument &Arg = TST->getArg(I); const TemplateArgument &Arg = TST->getArg(I);
if (Arg.getKind() == TemplateArgument::Type) if (Arg.getKind() == TemplateArgument::Type)
Args.push_back(Desugar(Context, Arg.getAsType(), DesugarArgument)); Args.push_back(desugarForDiagnostic(Context, Arg.getAsType(),
DesugarArgument));
else else
Args.push_back(Arg); 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. // Don't desugar magic Objective-C types.
if (QualType(Ty,0) == Context.getObjCIdType() || if (QualType(Ty,0) == Context.getObjCIdType() ||
QualType(Ty,0) == Context.getObjCClassType() || QualType(Ty,0) == Context.getObjCClassType() ||
@ -181,24 +211,25 @@ break; \
// If we have a pointer-like type, desugar the pointee as well. // If we have a pointer-like type, desugar the pointee as well.
// FIXME: Handle other pointer-like types. // FIXME: Handle other pointer-like types.
if (const PointerType *Ty = QT->getAs<PointerType>()) { if (const PointerType *Ty = QT->getAs<PointerType>()) {
QT = Context.getPointerType(Desugar(Context, Ty->getPointeeType(), QT = Context.getPointerType(
ShouldAKA)); desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
} else if (const auto *Ty = QT->getAs<ObjCObjectPointerType>()) { } else if (const auto *Ty = QT->getAs<ObjCObjectPointerType>()) {
QT = Context.getObjCObjectPointerType(Desugar(Context, Ty->getPointeeType(), QT = Context.getObjCObjectPointerType(
ShouldAKA)); desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
} else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) { } else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) {
QT = Context.getLValueReferenceType(Desugar(Context, Ty->getPointeeType(), QT = Context.getLValueReferenceType(
ShouldAKA)); desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
} else if (const RValueReferenceType *Ty = QT->getAs<RValueReferenceType>()) { } else if (const RValueReferenceType *Ty = QT->getAs<RValueReferenceType>()) {
QT = Context.getRValueReferenceType(Desugar(Context, Ty->getPointeeType(), QT = Context.getRValueReferenceType(
ShouldAKA)); desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
} else if (const auto *Ty = QT->getAs<ObjCObjectType>()) { } else if (const auto *Ty = QT->getAs<ObjCObjectType>()) {
if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) { if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {
QualType BaseType = Desugar(Context, Ty->getBaseType(), ShouldAKA); QualType BaseType =
QT = Context.getObjCObjectType(BaseType, Ty->getTypeArgsAsWritten(), desugarForDiagnostic(Context, Ty->getBaseType(), ShouldAKA);
llvm::makeArrayRef(Ty->qual_begin(), QT = Context.getObjCObjectType(
Ty->getNumProtocols()), BaseType, Ty->getTypeArgsAsWritten(),
Ty->isKindOfTypeAsWritten()); llvm::makeArrayRef(Ty->qual_begin(), Ty->getNumProtocols()),
Ty->isKindOfTypeAsWritten());
} }
} }
@ -251,7 +282,8 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
continue; // Same canonical types continue; // Same canonical types
std::string CompareS = CompareTy.getAsString(Context.getPrintingPolicy()); std::string CompareS = CompareTy.getAsString(Context.getPrintingPolicy());
bool ShouldAKA = false; bool ShouldAKA = false;
QualType CompareDesugar = Desugar(Context, CompareTy, ShouldAKA); QualType CompareDesugar =
desugarForDiagnostic(Context, CompareTy, ShouldAKA);
std::string CompareDesugarStr = std::string CompareDesugarStr =
CompareDesugar.getAsString(Context.getPrintingPolicy()); CompareDesugar.getAsString(Context.getPrintingPolicy());
if (CompareS != S && CompareDesugarStr != S) if (CompareS != S && CompareDesugarStr != S)
@ -286,7 +318,7 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
// sugar gives us something "significantly different". // sugar gives us something "significantly different".
if (!Repeated) { if (!Repeated) {
bool ShouldAKA = false; bool ShouldAKA = false;
QualType DesugaredTy = Desugar(Context, Ty, ShouldAKA); QualType DesugaredTy = desugarForDiagnostic(Context, Ty, ShouldAKA);
if (ShouldAKA || ForceAKA) { if (ShouldAKA || ForceAKA) {
if (DesugaredTy == Ty) { if (DesugaredTy == Ty) {
DesugaredTy = Ty.getCanonicalType(); DesugaredTy = Ty.getCanonicalType();
@ -308,7 +340,7 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '" OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '"
<< VTy->getElementType().getAsString(Context.getPrintingPolicy()) << VTy->getElementType().getAsString(Context.getPrintingPolicy())
<< "' " << Values << ")"; << "' " << Values << ")";
return OS.str(); return DecoratedString;
} }
} }

View File

@ -354,6 +354,7 @@ namespace clang {
ExpectedType VisitTypeOfExprType(const TypeOfExprType *T); ExpectedType VisitTypeOfExprType(const TypeOfExprType *T);
// FIXME: DependentTypeOfExprType // FIXME: DependentTypeOfExprType
ExpectedType VisitTypeOfType(const TypeOfType *T); ExpectedType VisitTypeOfType(const TypeOfType *T);
ExpectedType VisitUsingType(const UsingType *T);
ExpectedType VisitDecltypeType(const DecltypeType *T); ExpectedType VisitDecltypeType(const DecltypeType *T);
ExpectedType VisitUnaryTransformType(const UnaryTransformType *T); ExpectedType VisitUnaryTransformType(const UnaryTransformType *T);
ExpectedType VisitAutoType(const AutoType *T); ExpectedType VisitAutoType(const AutoType *T);
@ -1340,6 +1341,17 @@ ExpectedType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
return Importer.getToContext().getTypeOfType(*ToUnderlyingTypeOrErr); 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) { ExpectedType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
// FIXME: Make sure that the "to" context supports C++0x! // FIXME: Make sure that the "to" context supports C++0x!
ExpectedExpr ToExprOrErr = import(T->getUnderlyingExpr()); ExpectedExpr ToExprOrErr = import(T->getUnderlyingExpr());
@ -6066,20 +6078,24 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
if (Error Err = importInto(TemplatedFD, D->getTemplatedDecl())) if (Error Err = importInto(TemplatedFD, D->getTemplatedDecl()))
return std::move(Err); return std::move(Err);
// Template parameters of the ClassTemplateDecl and FunctionTemplateDecl are // At creation of the template the template parameters are "adopted"
// shared, if the FunctionTemplateDecl is a deduction guide for the class. // (DeclContext is changed). After this possible change the lookup table
// At import the ClassTemplateDecl object is always created first (FIXME: is // must be updated.
// this really true?) because the dependency, then the FunctionTemplateDecl. // At deduction guides the DeclContext of the template parameters may be
// The DeclContext of the template parameters is changed when the // different from what we would expect, it may be the class template, or a
// FunctionTemplateDecl is created, but was set already when the class // probably different CXXDeductionGuideDecl. This may come from the fact that
// template was created. So here it is not the TU (default value) any more. // the template parameter objects may be shared between deduction guides or
// FIXME: The DeclContext of the parameters is now set finally to the // the class template, and at creation of multiple FunctionTemplateDecl
// CXXDeductionGuideDecl object that was imported later. This may not be the // objects (for deduction guides) the same parameters are re-used. The
// same that is in the original AST, specially if there are multiple deduction // "adoption" happens multiple times with different parent, even recursively
// guides. // for TemplateTemplateParmDecl. The same happens at import when the
DeclContext *OldParamDC = nullptr; // FunctionTemplateDecl objects are created, but in different order.
if (Params->size() > 0) // In this way the DeclContext of these template parameters is not necessarily
OldParamDC = Params->getParam(0)->getDeclContext(); // 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; FunctionTemplateDecl *ToFunc;
if (GetImportedOrCreateDecl(ToFunc, D, Importer.getToContext(), DC, Loc, Name, if (GetImportedOrCreateDecl(ToFunc, D, Importer.getToContext(), DC, Loc, Name,
@ -6091,7 +6107,12 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
ToFunc->setAccess(D->getAccess()); ToFunc->setAccess(D->getAccess());
ToFunc->setLexicalDeclContext(LexicalDC); ToFunc->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToFunc); 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) { if (FoundByLookup) {
auto *Recent = auto *Recent =

View File

@ -140,6 +140,11 @@ void ASTImporterLookupTable::update(NamedDecl *ND, DeclContext *OldDC) {
add(ND); add(ND);
} }
void ASTImporterLookupTable::updateForced(NamedDecl *ND, DeclContext *OldDC) {
LookupTable[OldDC][ND->getDeclName()].remove(ND);
add(ND);
}
ASTImporterLookupTable::LookupResult ASTImporterLookupTable::LookupResult
ASTImporterLookupTable::lookup(DeclContext *DC, DeclarationName Name) const { ASTImporterLookupTable::lookup(DeclContext *DC, DeclarationName Name) const {
auto DCI = LookupTable.find(DC->getPrimaryContext()); auto DCI = LookupTable.find(DC->getPrimaryContext());

View File

@ -945,6 +945,12 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false; return false;
break; break;
case Type::Using:
if (!IsStructurallyEquivalent(Context, cast<UsingType>(T1)->getFoundDecl(),
cast<UsingType>(T2)->getFoundDecl()))
return false;
break;
case Type::Typedef: case Type::Typedef:
if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(), if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(),
cast<TypedefType>(T2)->getDecl())) cast<TypedefType>(T2)->getDecl()))
@ -1205,18 +1211,18 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
cast<PipeType>(T2)->getElementType())) cast<PipeType>(T2)->getElementType()))
return false; return false;
break; break;
case Type::ExtInt: { case Type::BitInt: {
const auto *Int1 = cast<ExtIntType>(T1); const auto *Int1 = cast<BitIntType>(T1);
const auto *Int2 = cast<ExtIntType>(T2); const auto *Int2 = cast<BitIntType>(T2);
if (Int1->isUnsigned() != Int2->isUnsigned() || if (Int1->isUnsigned() != Int2->isUnsigned() ||
Int1->getNumBits() != Int2->getNumBits()) Int1->getNumBits() != Int2->getNumBits())
return false; return false;
break; break;
} }
case Type::DependentExtInt: { case Type::DependentBitInt: {
const auto *Int1 = cast<DependentExtIntType>(T1); const auto *Int1 = cast<DependentBitIntType>(T1);
const auto *Int2 = cast<DependentExtIntType>(T2); const auto *Int2 = cast<DependentBitIntType>(T2);
if (Int1->isUnsigned() != Int2->isUnsigned() || if (Int1->isUnsigned() != Int2->isUnsigned() ||
!IsStructurallyEquivalent(Context, Int1->getNumBitsExpr(), !IsStructurallyEquivalent(Context, Int1->getNumBitsExpr(),

View File

@ -60,7 +60,7 @@ std::string LoopHintAttr::getValueString(const PrintingPolicy &Policy) const {
else else
OS << "disable"; OS << "disable";
OS << ")"; OS << ")";
return OS.str(); return ValueName;
} }
// Return a string suitable for identifying this attribute in diagnostics. // Return a string suitable for identifying this attribute in diagnostics.

View File

@ -108,12 +108,7 @@ Comment::child_iterator Comment::child_end() const {
} }
bool TextComment::isWhitespaceNoCache() const { bool TextComment::isWhitespaceNoCache() const {
for (StringRef::const_iterator I = Text.begin(), E = Text.end(); return llvm::all_of(Text, clang::isWhitespace);
I != E; ++I) {
if (!clang::isWhitespace(*I))
return false;
}
return true;
} }
bool ParagraphComment::isWhitespaceNoCache() const { bool ParagraphComment::isWhitespaceNoCache() const {

View File

@ -8,15 +8,12 @@
#include "clang/AST/CommentBriefParser.h" #include "clang/AST/CommentBriefParser.h"
#include "clang/AST/CommentCommandTraits.h" #include "clang/AST/CommentCommandTraits.h"
#include "clang/Basic/CharInfo.h"
namespace clang { namespace clang {
namespace comments { namespace comments {
namespace { 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, /// Convert all whitespace into spaces, remove leading and trailing spaces,
/// compress multiple spaces into one. /// compress multiple spaces into one.
@ -26,12 +23,11 @@ void cleanupBrief(std::string &S) {
for (std::string::iterator I = S.begin(), E = S.end(); for (std::string::iterator I = S.begin(), E = S.end();
I != E; ++I) { I != E; ++I) {
const char C = *I; const char C = *I;
if (isWhitespace(C)) { if (clang::isWhitespace(C)) {
if (!PrevWasSpace) { if (!PrevWasSpace) {
*O++ = ' '; *O++ = ' ';
PrevWasSpace = true; PrevWasSpace = true;
} }
continue;
} else { } else {
*O++ = C; *O++ = C;
PrevWasSpace = false; PrevWasSpace = false;
@ -44,12 +40,7 @@ void cleanupBrief(std::string &S) {
} }
bool isWhitespace(StringRef Text) { bool isWhitespace(StringRef Text) {
for (StringRef::const_iterator I = Text.begin(), E = Text.end(); return llvm::all_of(Text, clang::isWhitespace);
I != E; ++I) {
if (!isWhitespace(*I))
return false;
}
return true;
} }
} // unnamed namespace } // unnamed namespace

View File

@ -604,8 +604,14 @@ static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
// - A name declared at namespace scope that does not have internal linkage // - A name declared at namespace scope that does not have internal linkage
// by the previous rules and that is introduced by a non-exported // by the previous rules and that is introduced by a non-exported
// declaration has module linkage. // 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(ModuleLinkage, DefaultVisibility, false);
return LinkageInfo::external(); return LinkageInfo::external();
@ -1583,7 +1589,7 @@ std::string NamedDecl::getQualifiedNameAsString() const {
std::string QualName; std::string QualName;
llvm::raw_string_ostream OS(QualName); llvm::raw_string_ostream OS(QualName);
printQualifiedName(OS, getASTContext().getPrintingPolicy()); printQualifiedName(OS, getASTContext().getPrintingPolicy());
return OS.str(); return QualName;
} }
void NamedDecl::printQualifiedName(raw_ostream &OS) const { void NamedDecl::printQualifiedName(raw_ostream &OS) const {

View File

@ -236,7 +236,7 @@ std::string DeclarationName::getAsString() const {
std::string Result; std::string Result;
llvm::raw_string_ostream OS(Result); llvm::raw_string_ostream OS(Result);
OS << *this; OS << *this;
return OS.str(); return Result;
} }
void *DeclarationName::getFETokenInfoSlow() const { void *DeclarationName::getFETokenInfoSlow() const {
@ -460,7 +460,7 @@ std::string DeclarationNameInfo::getAsString() const {
std::string Result; std::string Result;
llvm::raw_string_ostream OS(Result); llvm::raw_string_ostream OS(Result);
OS << *this; OS << *this;
return OS.str(); return Result;
} }
raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) { raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {

View File

@ -202,6 +202,23 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const {
return false; 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 // Amusing macro metaprogramming hack: check whether a class provides
// a more specific implementation of getExprLoc(). // a more specific implementation of getExprLoc().
// //

View File

@ -1954,11 +1954,12 @@ static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E) {
return true; return true;
} }
/// Should this call expression be treated as a string literal? /// Should this call expression be treated as a constant?
static bool IsStringLiteralCall(const CallExpr *E) { static bool IsConstantCall(const CallExpr *E) {
unsigned Builtin = E->getBuiltinCallee(); unsigned Builtin = E->getBuiltinCallee();
return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString || 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) { static bool IsGlobalLValue(APValue::LValueBase B) {
@ -2004,7 +2005,7 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
case Expr::ObjCBoxedExprClass: case Expr::ObjCBoxedExprClass:
return cast<ObjCBoxedExpr>(E)->isExpressibleAsConstantInitializer(); return cast<ObjCBoxedExpr>(E)->isExpressibleAsConstantInitializer();
case Expr::CallExprClass: case Expr::CallExprClass:
return IsStringLiteralCall(cast<CallExpr>(E)); return IsConstantCall(cast<CallExpr>(E));
// For GCC compatibility, &&label has static storage duration. // For GCC compatibility, &&label has static storage duration.
case Expr::AddrLabelExprClass: case Expr::AddrLabelExprClass:
return true; return true;
@ -2931,6 +2932,11 @@ handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode,
break; 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; return true;
} }
@ -8965,7 +8971,7 @@ bool PointerExprEvaluator::visitNonBuiltinCallExpr(const CallExpr *E) {
} }
bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) { bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) {
if (IsStringLiteralCall(E)) if (IsConstantCall(E))
return Success(E); return Success(E);
if (unsigned BuiltinOp = E->getBuiltinCallee()) if (unsigned BuiltinOp = E->getBuiltinCallee())
@ -10182,7 +10188,8 @@ namespace {
bool VisitInitListExpr(const InitListExpr *E); bool VisitInitListExpr(const InitListExpr *E);
bool VisitUnaryImag(const UnaryOperator *E); bool VisitUnaryImag(const UnaryOperator *E);
bool VisitBinaryOperator(const BinaryOperator *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 // conditional select), shufflevector, ExtVectorElementExpr
}; };
} // end anonymous namespace } // end anonymous namespace
@ -10367,6 +10374,83 @@ bool VectorExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
return Success(LHSValue, 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 // Array Evaluation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -11080,7 +11164,7 @@ EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts) {
case Type::ObjCInterface: case Type::ObjCInterface:
case Type::ObjCObjectPointer: case Type::ObjCObjectPointer:
case Type::Pipe: case Type::Pipe:
case Type::ExtInt: case Type::BitInt:
// GCC classifies vectors as None. We follow its lead and classify all // 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. // other types that don't fit into the regular classification the same way.
return GCCTypeClass::None; return GCCTypeClass::None;

View File

@ -2263,8 +2263,8 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::Atomic: case Type::Atomic:
case Type::Pipe: case Type::Pipe:
case Type::MacroQualified: case Type::MacroQualified:
case Type::ExtInt: case Type::BitInt:
case Type::DependentExtInt: case Type::DependentBitInt:
llvm_unreachable("type is illegal as a nested name specifier"); llvm_unreachable("type is illegal as a nested name specifier");
case Type::SubstTemplateTypeParmPack: case Type::SubstTemplateTypeParmPack:
@ -2380,6 +2380,9 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
break; break;
} }
case Type::Using:
return mangleUnresolvedTypeOrSimpleId(cast<UsingType>(Ty)->desugar(),
Prefix);
case Type::Elaborated: case Type::Elaborated:
return mangleUnresolvedTypeOrSimpleId( return mangleUnresolvedTypeOrSimpleId(
cast<ElaboratedType>(Ty)->getNamedType(), Prefix); cast<ElaboratedType>(Ty)->getNamedType(), Prefix);
@ -3967,26 +3970,20 @@ void CXXNameMangler::mangleType(const PipeType *T) {
Out << "8ocl_pipe"; Out << "8ocl_pipe";
} }
void CXXNameMangler::mangleType(const ExtIntType *T) { void CXXNameMangler::mangleType(const BitIntType *T) {
Out << "U7_ExtInt"; // 5.1.5.2 Builtin types
llvm::APSInt BW(32, true); // <type> ::= DB <number | instantiation-dependent expression> _
BW = T->getNumBits(); // ::= DU <number | instantiation-dependent expression> _
TemplateArgument TA(Context.getASTContext(), BW, getASTContext().IntTy); Out << "D" << (T->isUnsigned() ? "U" : "B") << T->getNumBits() << "_";
mangleTemplateArgs(TemplateName(), &TA, 1);
if (T->isUnsigned())
Out << "j";
else
Out << "i";
} }
void CXXNameMangler::mangleType(const DependentExtIntType *T) { void CXXNameMangler::mangleType(const DependentBitIntType *T) {
Out << "U7_ExtInt"; // 5.1.5.2 Builtin types
TemplateArgument TA(T->getNumBitsExpr()); // <type> ::= DB <number | instantiation-dependent expression> _
mangleTemplateArgs(TemplateName(), &TA, 1); // ::= DU <number | instantiation-dependent expression> _
if (T->isUnsigned()) Out << "D" << (T->isUnsigned() ? "U" : "B");
Out << "j"; mangleExpression(T->getNumBitsExpr());
else Out << "_";
Out << "i";
} }
void CXXNameMangler::mangleIntegerLiteral(QualType T, void CXXNameMangler::mangleIntegerLiteral(QualType T,

View File

@ -744,11 +744,18 @@ void JSONNodeDumper::VisitNamedDecl(const NamedDecl *ND) {
JOS.attribute("name", ND->getNameAsString()); JOS.attribute("name", ND->getNameAsString());
// FIXME: There are likely other contexts in which it makes no sense to ask // FIXME: There are likely other contexts in which it makes no sense to ask
// for a mangled name. // for a mangled name.
if (!isa<RequiresExprBodyDecl>(ND->getDeclContext())) { if (isa<RequiresExprBodyDecl>(ND->getDeclContext()))
std::string MangledName = ASTNameGen.getName(ND); return;
if (!MangledName.empty())
JOS.attribute("mangledName", MangledName); // 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);
} }
} }

View File

@ -3365,26 +3365,26 @@ void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
return Mangler.mangle(GD); return Mangler.mangle(GD);
} }
void MicrosoftCXXNameMangler::mangleType(const ExtIntType *T, Qualifiers, void MicrosoftCXXNameMangler::mangleType(const BitIntType *T, Qualifiers,
SourceRange Range) { SourceRange Range) {
llvm::SmallString<64> TemplateMangling; llvm::SmallString<64> TemplateMangling;
llvm::raw_svector_ostream Stream(TemplateMangling); llvm::raw_svector_ostream Stream(TemplateMangling);
MicrosoftCXXNameMangler Extra(Context, Stream); MicrosoftCXXNameMangler Extra(Context, Stream);
Stream << "?$"; Stream << "?$";
if (T->isUnsigned()) if (T->isUnsigned())
Extra.mangleSourceName("_UExtInt"); Extra.mangleSourceName("_UBitInt");
else else
Extra.mangleSourceName("_ExtInt"); Extra.mangleSourceName("_BitInt");
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits())); Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()));
mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"}); mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
} }
void MicrosoftCXXNameMangler::mangleType(const DependentExtIntType *T, void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,
Qualifiers, SourceRange Range) { Qualifiers, SourceRange Range) {
DiagnosticsEngine &Diags = Context.getDiags(); DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID( 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; Diags.Report(Range.getBegin(), DiagID) << Range;
} }

View File

@ -126,6 +126,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_write: case OMPC_write:
case OMPC_update: case OMPC_update:
case OMPC_capture: case OMPC_capture:
case OMPC_compare:
case OMPC_seq_cst: case OMPC_seq_cst:
case OMPC_acq_rel: case OMPC_acq_rel:
case OMPC_acquire: case OMPC_acquire:
@ -217,6 +218,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_write: case OMPC_write:
case OMPC_update: case OMPC_update:
case OMPC_capture: case OMPC_capture:
case OMPC_compare:
case OMPC_seq_cst: case OMPC_seq_cst:
case OMPC_acq_rel: case OMPC_acq_rel:
case OMPC_acquire: case OMPC_acquire:
@ -1792,6 +1794,10 @@ void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
OS << "capture"; OS << "capture";
} }
void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {
OS << "compare";
}
void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) { void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
OS << "seq_cst"; OS << "seq_cst";
} }
@ -2454,7 +2460,7 @@ std::string OMPTraitInfo::getMangledName() const {
Property.RawString); Property.RawString);
} }
} }
return OS.str(); return MangledName;
} }
OMPTraitInfo::OMPTraitInfo(StringRef MangledName) { OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {

View File

@ -133,8 +133,7 @@ void ParentMap::setParent(const Stmt *S, const Stmt *Parent) {
Stmt* ParentMap::getParent(Stmt* S) const { Stmt* ParentMap::getParent(Stmt* S) const {
MapTy* M = (MapTy*) Impl; MapTy* M = (MapTy*) Impl;
MapTy::iterator I = M->find(S); return M->lookup(S);
return I == M->end() ? nullptr : I->second;
} }
Stmt *ParentMap::getParentIgnoreParens(Stmt *S) const { Stmt *ParentMap::getParentIgnoreParens(Stmt *S) const {

View File

@ -418,6 +418,13 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
return QT; 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 // 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 // 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 // is actually make the code below to be more complex (to handle

View File

@ -551,6 +551,8 @@ void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {}
void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {} void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
void OMPClauseProfiler::VisitOMPCompareClause(const OMPCompareClause *) {}
void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {} void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {} void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}

View File

@ -1534,6 +1534,10 @@ void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
dumpDeclRef(T->getDecl()); dumpDeclRef(T->getDecl());
} }
void TextNodeDumper::VisitUsingType(const UsingType *T) {
dumpDeclRef(T->getFoundDecl());
}
void TextNodeDumper::VisitTypedefType(const TypedefType *T) { void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
dumpDeclRef(T->getDecl()); dumpDeclRef(T->getDecl());
} }

View File

@ -338,25 +338,25 @@ VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements,
VectorTypeBits.NumElements = nElements; VectorTypeBits.NumElements = nElements;
} }
ExtIntType::ExtIntType(bool IsUnsigned, unsigned NumBits) BitIntType::BitIntType(bool IsUnsigned, unsigned NumBits)
: Type(ExtInt, QualType{}, TypeDependence::None), IsUnsigned(IsUnsigned), : Type(BitInt, QualType{}, TypeDependence::None), IsUnsigned(IsUnsigned),
NumBits(NumBits) {} NumBits(NumBits) {}
DependentExtIntType::DependentExtIntType(const ASTContext &Context, DependentBitIntType::DependentBitIntType(const ASTContext &Context,
bool IsUnsigned, Expr *NumBitsExpr) bool IsUnsigned, Expr *NumBitsExpr)
: Type(DependentExtInt, QualType{}, : Type(DependentBitInt, QualType{},
toTypeDependence(NumBitsExpr->getDependence())), toTypeDependence(NumBitsExpr->getDependence())),
Context(Context), ExprAndUnsigned(NumBitsExpr, IsUnsigned) {} Context(Context), ExprAndUnsigned(NumBitsExpr, IsUnsigned) {}
bool DependentExtIntType::isUnsigned() const { bool DependentBitIntType::isUnsigned() const {
return ExprAndUnsigned.getInt(); return ExprAndUnsigned.getInt();
} }
clang::Expr *DependentExtIntType::getNumBitsExpr() const { clang::Expr *DependentBitIntType::getNumBitsExpr() const {
return ExprAndUnsigned.getPointer(); return ExprAndUnsigned.getPointer();
} }
void DependentExtIntType::Profile(llvm::FoldingSetNodeID &ID, void DependentBitIntType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context, bool IsUnsigned, const ASTContext &Context, bool IsUnsigned,
Expr *NumBitsExpr) { Expr *NumBitsExpr) {
ID.AddBoolean(IsUnsigned); ID.AddBoolean(IsUnsigned);
@ -1932,7 +1932,7 @@ bool Type::isIntegralType(const ASTContext &Ctx) const {
if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
return ET->getDecl()->isComplete(); return ET->getDecl()->isComplete();
return isExtIntType(); return isBitIntType();
} }
bool Type::isIntegralOrUnscopedEnumerationType() const { bool Type::isIntegralOrUnscopedEnumerationType() const {
@ -1940,7 +1940,7 @@ bool Type::isIntegralOrUnscopedEnumerationType() const {
return BT->getKind() >= BuiltinType::Bool && return BT->getKind() >= BuiltinType::Bool &&
BT->getKind() <= BuiltinType::Int128; BT->getKind() <= BuiltinType::Int128;
if (isExtIntType()) if (isBitIntType())
return true; return true;
return isUnscopedEnumerationType(); return isUnscopedEnumerationType();
@ -2023,7 +2023,9 @@ bool Type::isSignedIntegerType() const {
return ET->getDecl()->getIntegerType()->isSignedIntegerType(); 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 IT->isSigned();
return false; return false;
@ -2040,9 +2042,10 @@ bool Type::isSignedIntegerOrEnumerationType() const {
return ET->getDecl()->getIntegerType()->isSignedIntegerType(); 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 IT->isSigned();
return false; return false;
} }
@ -2070,7 +2073,9 @@ bool Type::isUnsignedIntegerType() const {
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType(); 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 IT->isUnsigned();
return false; return false;
@ -2087,7 +2092,9 @@ bool Type::isUnsignedIntegerOrEnumerationType() const {
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType(); 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 IT->isUnsigned();
return false; return false;
@ -2129,7 +2136,7 @@ bool Type::isRealType() const {
BT->getKind() <= BuiltinType::Ibm128; BT->getKind() <= BuiltinType::Ibm128;
if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped(); return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
return isExtIntType(); return isBitIntType();
} }
bool Type::isArithmeticType() const { bool Type::isArithmeticType() const {
@ -2145,7 +2152,7 @@ bool Type::isArithmeticType() const {
// false for scoped enumerations since that will disable any // false for scoped enumerations since that will disable any
// unwanted implicit conversions. // unwanted implicit conversions.
return !ET->getDecl()->isScoped() && ET->getDecl()->isComplete(); return !ET->getDecl()->isScoped() && ET->getDecl()->isComplete();
return isa<ComplexType>(CanonicalType) || isExtIntType(); return isa<ComplexType>(CanonicalType) || isBitIntType();
} }
Type::ScalarTypeKind Type::getScalarTypeKind() const { Type::ScalarTypeKind Type::getScalarTypeKind() const {
@ -2174,7 +2181,7 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const {
if (CT->getElementType()->isRealFloatingType()) if (CT->getElementType()->isRealFloatingType())
return STK_FloatingComplex; return STK_FloatingComplex;
return STK_IntegralComplex; return STK_IntegralComplex;
} else if (isExtIntType()) { } else if (isBitIntType()) {
return STK_Integral; return STK_Integral;
} }
@ -2381,7 +2388,7 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const {
case Type::MemberPointer: case Type::MemberPointer:
case Type::Vector: case Type::Vector:
case Type::ExtVector: case Type::ExtVector:
case Type::ExtInt: case Type::BitInt:
return true; return true;
case Type::Enum: case Type::Enum:
@ -3400,6 +3407,17 @@ QualType TypedefType::desugar() const {
return getDecl()->getUnderlyingType(); 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::desugar() const { return getUnderlyingType(); }
QualType MacroQualifiedType::getModifiedType() const { QualType MacroQualifiedType::getModifiedType() const {
@ -3849,7 +3867,7 @@ static CachedProperties computeCachedProperties(const Type *T) {
// here in error recovery. // here in error recovery.
return CachedProperties(ExternalLinkage, false); return CachedProperties(ExternalLinkage, false);
case Type::ExtInt: case Type::BitInt:
case Type::Builtin: case Type::Builtin:
// C++ [basic.link]p8: // C++ [basic.link]p8:
// A type is said to have linkage if and only if: // A type is said to have linkage if and only if:
@ -3949,7 +3967,7 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
assert(T->isInstantiationDependentType()); assert(T->isInstantiationDependentType());
return LinkageInfo::external(); return LinkageInfo::external();
case Type::ExtInt: case Type::BitInt:
case Type::Builtin: case Type::Builtin:
return LinkageInfo::external(); return LinkageInfo::external();
@ -4169,8 +4187,8 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case Type::ObjCInterface: case Type::ObjCInterface:
case Type::Atomic: case Type::Atomic:
case Type::Pipe: case Type::Pipe:
case Type::ExtInt: case Type::BitInt:
case Type::DependentExtInt: case Type::DependentBitInt:
return false; return false;
} }
llvm_unreachable("bad type kind!"); llvm_unreachable("bad type kind!");

View File

@ -212,6 +212,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
case Type::Builtin: case Type::Builtin:
case Type::Complex: case Type::Complex:
case Type::UnresolvedUsing: case Type::UnresolvedUsing:
case Type::Using:
case Type::Typedef: case Type::Typedef:
case Type::TypeOfExpr: case Type::TypeOfExpr:
case Type::TypeOf: case Type::TypeOf:
@ -232,8 +233,8 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
case Type::ObjCInterface: case Type::ObjCInterface:
case Type::Atomic: case Type::Atomic:
case Type::Pipe: case Type::Pipe:
case Type::ExtInt: case Type::BitInt:
case Type::DependentExtInt: case Type::DependentBitInt:
CanPrefixQualifiers = true; CanPrefixQualifiers = true;
break; break;
@ -1046,6 +1047,21 @@ void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T, void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
raw_ostream &OS) {} 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) { void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
printTypeSpec(T->getDecl(), 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::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()) if (T->isUnsigned())
OS << "unsigned "; OS << "unsigned ";
OS << "_ExtInt(" << T->getNumBits() << ")"; OS << "_BitInt(" << T->getNumBits() << ")";
spaceBeforePlaceHolder(OS); 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) { raw_ostream &OS) {
if (T->isUnsigned()) if (T->isUnsigned())
OS << "unsigned "; OS << "unsigned ";
OS << "_ExtInt("; OS << "_BitInt(";
T->getNumBitsExpr()->printPretty(OS, nullptr, Policy); T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
OS << ")"; OS << ")";
spaceBeforePlaceHolder(OS); spaceBeforePlaceHolder(OS);
} }
void TypePrinter::printDependentExtIntAfter(const DependentExtIntType *T, void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
raw_ostream &OS) {} raw_ostream &OS) {}
/// Appends the given scope to the end of a string. /// Appends the given scope to the end of a string.

View File

@ -1059,6 +1059,7 @@ const AstTypeMatcher<UnaryTransformType> unaryTransformType;
const AstTypeMatcher<RecordType> recordType; const AstTypeMatcher<RecordType> recordType;
const AstTypeMatcher<TagType> tagType; const AstTypeMatcher<TagType> tagType;
const AstTypeMatcher<ElaboratedType> elaboratedType; const AstTypeMatcher<ElaboratedType> elaboratedType;
const AstTypeMatcher<UsingType> usingType;
const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType; const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType;
const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType; const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
const AstTypeMatcher<InjectedClassNameType> injectedClassNameType; const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;

View File

@ -204,7 +204,7 @@ std::string Diagnostics::toString() const {
std::string S; std::string S;
llvm::raw_string_ostream OS(S); llvm::raw_string_ostream OS(S);
printToStream(OS); printToStream(OS);
return OS.str(); return S;
} }
void Diagnostics::printToStreamFull(llvm::raw_ostream &OS) const { void Diagnostics::printToStreamFull(llvm::raw_ostream &OS) const {
@ -223,7 +223,7 @@ std::string Diagnostics::toStringFull() const {
std::string S; std::string S;
llvm::raw_string_ostream OS(S); llvm::raw_string_ostream OS(S);
printToStreamFull(OS); printToStreamFull(OS);
return OS.str(); return S;
} }
} // namespace dynamic } // namespace dynamic

View File

@ -1035,7 +1035,6 @@ class MapAnyOfBuilderDescriptor : public MatcherDescriptor {
void getArgKinds(ASTNodeKind ThisKind, unsigned, void getArgKinds(ASTNodeKind ThisKind, unsigned,
std::vector<ArgKind> &ArgKinds) const override { std::vector<ArgKind> &ArgKinds) const override {
ArgKinds.push_back(ArgKind::MakeNodeArg(ThisKind)); ArgKinds.push_back(ArgKind::MakeNodeArg(ThisKind));
return;
} }
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity = nullptr, bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity = nullptr,
ASTNodeKind *LeastDerivedKind = nullptr) const override { ASTNodeKind *LeastDerivedKind = nullptr) const override {

View File

@ -645,7 +645,7 @@ bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
Tokenizer->SkipNewlines(); Tokenizer->SkipNewlines();
{ {
ScopedContextEntry SCE(this, Ctor ? *Ctor : nullptr); ScopedContextEntry SCE(this, Ctor.getValueOr(nullptr));
while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) { while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) { if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) {

View File

@ -228,6 +228,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(eachOf); REGISTER_MATCHER(eachOf);
REGISTER_MATCHER(elaboratedType); REGISTER_MATCHER(elaboratedType);
REGISTER_MATCHER(elaboratedTypeLoc); REGISTER_MATCHER(elaboratedTypeLoc);
REGISTER_MATCHER(usingType);
REGISTER_MATCHER(enumConstantDecl); REGISTER_MATCHER(enumConstantDecl);
REGISTER_MATCHER(enumDecl); REGISTER_MATCHER(enumDecl);
REGISTER_MATCHER(enumType); REGISTER_MATCHER(enumType);

View File

@ -387,7 +387,7 @@ std::string AnalysisDeclContext::getFunctionName(const Decl *D) {
OS << ' ' << OMD->getSelector().getAsString() << ']'; OS << ' ' << OMD->getSelector().getAsString() << ']';
} }
return OS.str(); return Str;
} }
LocationContextManager &AnalysisDeclContext::getLocationContextManager() { LocationContextManager &AnalysisDeclContext::getLocationContextManager() {

View File

@ -1820,8 +1820,6 @@ void CFGBuilder::addScopesEnd(LocalScope::const_iterator B,
for (VarDecl *VD : llvm::reverse(DeclsWithEndedScope)) for (VarDecl *VD : llvm::reverse(DeclsWithEndedScope))
appendScopeEnd(Block, VD, S); appendScopeEnd(Block, VD, S);
return;
} }
/// addAutomaticObjDtors - Add to current block automatic objects destructors /// addAutomaticObjDtors - Add to current block automatic objects destructors

View File

@ -11,15 +11,82 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include <utility>
#include <vector> #include <vector>
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/CFG.h" #include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/DataflowWorklist.h"
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h" #include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang; namespace clang {
using namespace dataflow; 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>> std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>>
runTypeErasedDataflowAnalysis(const CFG &Cfg, runTypeErasedDataflowAnalysis(const CFG &Cfg,
@ -29,7 +96,59 @@ runTypeErasedDataflowAnalysis(const CFG &Cfg,
// are specified in the header. This could be done by remembering // are specified in the header. This could be done by remembering
// what options were used to build `Cfg` and asserting on them here. // what options were used to build `Cfg` and asserting on them here.
// FIXME: Implement work list-based algorithm to compute the fixed PostOrderCFGView POV(&Cfg);
// point of `Analysis::transform` for every basic block in `Cfg`. ForwardDataflowWorklist Worklist(Cfg, &POV);
return {};
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

View File

@ -418,7 +418,6 @@ class LocalVariableMap {
private: private:
Context::Factory ContextFactory; Context::Factory ContextFactory;
std::vector<VarDefinition> VarDefinitions; std::vector<VarDefinition> VarDefinitions;
std::vector<unsigned> CtxIndices;
std::vector<std::pair<const Stmt *, Context>> SavedContexts; std::vector<std::pair<const Stmt *, Context>> SavedContexts;
public: public:
@ -731,8 +730,6 @@ void LocalVariableMap::traverseCFG(CFG *CFGraph,
std::vector<CFGBlockInfo> &BlockInfo) { std::vector<CFGBlockInfo> &BlockInfo) {
PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph); PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
CtxIndices.resize(CFGraph->getNumBlockIDs());
for (const auto *CurrBlock : *SortedGraph) { for (const auto *CurrBlock : *SortedGraph) {
unsigned CurrBlockID = CurrBlock->getBlockID(); unsigned CurrBlockID = CurrBlock->getBlockID();
CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID]; CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];

View File

@ -591,8 +591,8 @@ class TransferFunctions : public StmtVisitor<TransferFunctions> {
if (AtPredExit == MayUninitialized) { if (AtPredExit == MayUninitialized) {
// If the predecessor's terminator is an "asm goto" that initializes // If the predecessor's terminator is an "asm goto" that initializes
// the variable, then it won't be counted as "initialized" on the // the variable, then don't count it as "initialized" on the indirect
// non-fallthrough paths. // paths.
CFGTerminator term = Pred->getTerminator(); CFGTerminator term = Pred->getTerminator();
if (const auto *as = dyn_cast_or_null<GCCAsmStmt>(term.getStmt())) { if (const auto *as = dyn_cast_or_null<GCCAsmStmt>(term.getStmt())) {
const CFGBlock *fallthrough = *Pred->succ_begin(); const CFGBlock *fallthrough = *Pred->succ_begin();
@ -810,13 +810,22 @@ void TransferFunctions::VisitGCCAsmStmt(GCCAsmStmt *as) {
if (!as->isAsmGoto()) if (!as->isAsmGoto())
return; return;
for (const Expr *o : as->outputs()) ASTContext &C = ac.getASTContext();
if (const VarDecl *VD = findVar(o).getDecl()) 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 (vals[VD] != Initialized)
// If the variable isn't initialized by the time we get here, then we // 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 // mark it as potentially uninitialized for those cases where it's used
// on an indirect path, where it's not guaranteed to be defined. // on an indirect path, where it's not guaranteed to be defined.
vals[VD] = MayUninitialized; vals[VD] = MayUninitialized;
}
} }
void TransferFunctions::VisitObjCMessageExpr(ObjCMessageExpr *ME) { void TransferFunctions::VisitObjCMessageExpr(ObjCMessageExpr *ME) {

View File

@ -123,6 +123,7 @@ static const CudaArchToStringMap arch_names[] = {
GFX(1033), // gfx1033 GFX(1033), // gfx1033
GFX(1034), // gfx1034 GFX(1034), // gfx1034
GFX(1035), // gfx1035 GFX(1035), // gfx1035
{CudaArch::Generic, "generic", ""},
// clang-format on // clang-format on
}; };
#undef SM #undef SM

View File

@ -163,6 +163,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
case OMPC_read: case OMPC_read:
case OMPC_write: case OMPC_write:
case OMPC_capture: case OMPC_capture:
case OMPC_compare:
case OMPC_seq_cst: case OMPC_seq_cst:
case OMPC_acq_rel: case OMPC_acq_rel:
case OMPC_acquire: case OMPC_acquire:
@ -428,6 +429,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_read: case OMPC_read:
case OMPC_write: case OMPC_write:
case OMPC_capture: case OMPC_capture:
case OMPC_compare:
case OMPC_seq_cst: case OMPC_seq_cst:
case OMPC_acq_rel: case OMPC_acq_rel:
case OMPC_acquire: case OMPC_acquire:

View File

@ -90,7 +90,7 @@ SourceLocation::printToString(const SourceManager &SM) const {
std::string S; std::string S;
llvm::raw_string_ostream OS(S); llvm::raw_string_ostream OS(S);
print(OS, SM); print(OS, SM);
return OS.str(); return S;
} }
LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const { LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const {
@ -149,7 +149,7 @@ SourceRange::printToString(const SourceManager &SM) const {
std::string S; std::string S;
llvm::raw_string_ostream OS(S); llvm::raw_string_ostream OS(S);
print(OS, SM); print(OS, SM);
return OS.str(); return S;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -307,6 +307,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (FPU & SveMode) if (FPU & SveMode)
Builder.defineMacro("__ARM_FEATURE_SVE", "1"); Builder.defineMacro("__ARM_FEATURE_SVE", "1");
if ((FPU & NeonMode) && (FPU & SveMode))
Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");
if (HasSVE2) if (HasSVE2)
Builder.defineMacro("__ARM_FEATURE_SVE2", "1"); Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
@ -474,10 +477,12 @@ ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
Optional<std::pair<unsigned, unsigned>> Optional<std::pair<unsigned, unsigned>>
AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const { AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
if (LangOpts.VScaleMin || LangOpts.VScaleMax) if (LangOpts.VScaleMin || LangOpts.VScaleMax)
return std::pair<unsigned, unsigned>(LangOpts.VScaleMin, return std::pair<unsigned, unsigned>(
LangOpts.VScaleMax); LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax);
if (hasFeature("sve")) if (hasFeature("sve"))
return std::pair<unsigned, unsigned>(0, 16); return std::pair<unsigned, unsigned>(1, 16);
return None; return None;
} }

View File

@ -150,7 +150,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
const char *getBFloat16Mangling() const override { return "u6__bf16"; }; const char *getBFloat16Mangling() const override { return "u6__bf16"; };
bool hasInt128Type() const override; bool hasInt128Type() const override;
bool hasExtIntType() const override { return true; } bool hasBitIntType() const override { return true; }
}; };
class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo { class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo {

Some files were not shown because too many files have changed in this diff Show More