diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -565,6 +565,8 @@ const TargetInfo *AuxTarget = nullptr; clang::PrintingPolicy PrintingPolicy; + ArrayRef Argv; + public: IdentifierTable &Idents; SelectorTable &Selectors; @@ -662,6 +664,14 @@ PrintingPolicy = Policy; } + void setCmdLineArgs(ArrayRef _Argv) { + Argv = _Argv; + } + + ArrayRef getCmdLineArgs() const { + return Argv; + } + SourceManager& getSourceManager() { return SourceMgr; } const SourceManager& getSourceManager() const { return SourceMgr; } @@ -1036,7 +1046,7 @@ CanQualType SatUnsignedShortFractTy, SatUnsignedFractTy, SatUnsignedLongFractTy; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON - CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 + CanQualType Float16Ty, Float16ComplexTy; // C11 extension ISO/IEC TS 18661-3 CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; CanQualType Float128ComplexTy; CanQualType VoidPtrTy, NullPtrTy; @@ -1063,6 +1073,8 @@ // The decl is built when constructing 'BuiltinVaListDecl'. mutable Decl *VaListTagDecl; + mutable SmallVector CanQualTypes; + ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins); ASTContext(const ASTContext &) = delete; @@ -1345,6 +1357,9 @@ /// \pre \p VectorType must be a built-in type. QualType getVectorType(QualType VectorType, unsigned NumElts, VectorType::VectorKind VecKind) const; + + QualType getScalableVectorType(QualType ElementType) const; + /// Return the unique reference to the type for a dependently sized vector of /// the specified element type. QualType getDependentVectorType(QualType VectorType, Expr *SizeExpr, @@ -1420,7 +1435,7 @@ QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const; - QualType getAttributedType(attr::Kind attrKind, + QualType getAttributedType(AttributedType::Kind attrKind, QualType modifiedType, QualType equivalentType); @@ -2881,6 +2896,7 @@ private: void InitBuiltinType(CanQualType &R, BuiltinType::Kind K); + void InitTargetBuiltinType(BuiltinType::Kind K, int TD); class ObjCEncOptions { unsigned Bits; diff --git a/clang/include/clang/AST/BuiltinTypesSVE.def b/clang/include/clang/AST/BuiltinTypesSVE.def new file mode 100644 --- /dev/null +++ b/clang/include/clang/AST/BuiltinTypesSVE.def @@ -0,0 +1,57 @@ +//===-- BuiltinTypesSVE.def - Metadata about BuiltinTypes -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the database about various builtin singleton types. +// +// BuiltinType::Id is the enumerator defining the type. +// +// Context.SingletonId is the global singleton of this type. Some global +// singletons are shared by multiple types. +// +// BUILTIN_TYPE(Id, SingletonId) - A builtin type that has not been +// covered by any other #define. Defining this macro covers all +// the builtins. +// +// SVE_VECTOR_TYPE(Id, SingletonId) - A scalable vector. +// +// SVE_PREDICATE_TYPE(Id, SingletonId) - A scalable predicate. +// +//===----------------------------------------------------------------------===// + +#ifndef SVE_VECTOR_TYPE +#define SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP)\ + BUILTIN_TYPE(Name, Id, SingletonId) +#endif + +#ifndef SVE_PREDICATE_TYPE +#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind)\ + BUILTIN_TYPE(Name, Id, SingletonId) +#endif + +//===- Vector point types -----------------------------------------------===// + +SVE_VECTOR_TYPE("__SVInt8_t", SveInt8, SveInt8Ty, SveElSInt8, 8, true, false) +SVE_VECTOR_TYPE("__SVInt16_t", SveInt16, SveInt16Ty, SveElSInt16, 16, true, false) +SVE_VECTOR_TYPE("__SVInt32_t", SveInt32, SveInt32Ty, SveElSInt32, 32, true, false) +SVE_VECTOR_TYPE("__SVInt64_t", SveInt64, SveInt64Ty, SveElSInt64, 64, true, false) + +SVE_VECTOR_TYPE("__SVUint8_t", SveUint8, SveUint8Ty, SveElUInt8, 8, false, false) +SVE_VECTOR_TYPE("__SVUint16_t", SveUint16, SveUint16Ty, SveElUInt16, 16, false, false) +SVE_VECTOR_TYPE("__SVUint32_t", SveUint32, SveUint32Ty, SveElUInt32, 32, false, false) +SVE_VECTOR_TYPE("__SVUint64_t", SveUint64, SveUint64Ty, SveElUInt64, 64, false, false) + +SVE_VECTOR_TYPE("__SVFloat16_t", SveFloat16, SveFloat16Ty, SveElHalf, 16, true, true) +SVE_VECTOR_TYPE("__SVFloat32_t", SveFloat32, SveFloat32Ty, SveElFloat, 32, true, true) +SVE_VECTOR_TYPE("__SVFloat64_t", SveFloat64, SveFloat64Ty, SveElDouble, 64, true, true) + +SVE_PREDICATE_TYPE("__SVBool_t", SveBool, SveBoolTy, SveElBool) + +#undef SVE_VECTOR_TYPE +#undef SVE_PREDICATE_TYPE +#undef BUILTIN_TYPE diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h --- a/clang/include/clang/AST/CanonicalType.h +++ b/clang/include/clang/AST/CanonicalType.h @@ -264,6 +264,9 @@ // Type predicates LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIndefiniteType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessBuiltinType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -3280,6 +3280,7 @@ void setTagKind(TagKind TK) { TagDeclBits.TagDeclKind = TK; } bool isStruct() const { return getTagKind() == TTK_Struct; } + bool isSizelessStruct() const { return getTagKind() == TTK_SizelessStruct; } bool isInterface() const { return getTagKind() == TTK_Interface; } bool isClass() const { return getTagKind() == TTK_Class; } bool isUnion() const { return getTagKind() == TTK_Union; } diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -282,7 +282,7 @@ MLV_DuplicateVectorComponents, MLV_InvalidExpression, MLV_LValueCast, // Specialized form of MLV_InvalidExpression. - MLV_IncompleteType, + MLV_IndefiniteType, MLV_ConstQualified, MLV_ConstQualifiedField, MLV_ConstAddrSpace, @@ -337,7 +337,7 @@ CM_ConstQualifiedField, CM_ConstAddrSpace, CM_ArrayType, - CM_IncompleteType + CM_IndefiniteType }; private: diff --git a/clang/include/clang/AST/TargetTypes.h b/clang/include/clang/AST/TargetTypes.h new file mode 100644 --- /dev/null +++ b/clang/include/clang/AST/TargetTypes.h @@ -0,0 +1,35 @@ +//===--- TargetBuiltinTypes.h - Target specific builtin IDs -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Enumerates target-specific builtin types in their own namespaces +/// within namespace ::clang. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_TARGETTYPES_H +#define LLVM_CLANG_AST_TARGETTYPES_H + +#include +#include "clang/AST/Type.h" + +namespace clang { + + namespace SVE { + enum { + LastTIBuiltinType = clang::BuiltinType::LastTIBuiltinType, +#define BUILTIN_TYPE(Name, Id, SingletonId) Id, +#include "clang/AST/BuiltinTypesSVE.def" + LastTSBuiltinType + }; + } + +} // end namespace clang. + +#endif diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -38,6 +38,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Casting.h" @@ -1518,7 +1519,14 @@ /// The kind (BuiltinType::Kind) of builtin type this is. unsigned Kind : 8; + + /// What target is this for? + unsigned Target : 6; + + /// Target specific detail, such as features, etc. + unsigned TargetDetail : 2; }; + static_assert(llvm::Triple::LastArchType <= 63, "Does not fit in 6 bits"); /// FunctionTypeBitfields store various bits belonging to FunctionProtoType. /// Only common bits are stored here. Additional uncommon bits are stored @@ -1871,18 +1879,43 @@ /// or QualType::getSingleStepDesugaredType(const ASTContext&). QualType getLocallyUnqualifiedSingleStepDesugaredType() const; - /// Types are partitioned into 3 broad categories (C99 6.2.5p1): - /// object types, function types, and incomplete types. + /// As an extension, we classify types as one of "indefinite" or "definite"; + /// every type is one or the other. Indefinite types are types that can + /// describe objects but don't have enough information to construct them. + /// A type is indefinite iff: + /// - it is "incomplete" according to the standard definition; or + /// - it is a sizeless struct whose body has not yet been defined. + /// + /// \brief Def If non-null, and the type refers to some kind of declaration + /// that can be made definite (such as a C struct, C++ class, or Objective-C + /// class), will be set to the declaration. + bool isIndefiniteType(NamedDecl **Def = nullptr) const; + + /// As an extension, we classify types as one of "sized" or "sizeless"; + /// every type is one or the other. Standard types are all sized; + /// sizeless types are purely an extension. + /// + /// Sizeless types contain data with no specified size, alignment, + /// or layout. They are always incomplete. + bool isSizelessType() const; + bool isSizelessBuiltinType() const; /// Return true if this is an incomplete type. /// A type that can describe objects, but which lacks information needed to /// determine its size (e.g. void, or a fwd declared struct). Clients of this /// routine will need to determine if the size is actually required. /// - /// Def If non-null, and the type refers to some kind of declaration - /// that can be completed (such as a C struct, C++ class, or Objective-C - /// class), will be set to the declaration. - bool isIncompleteType(NamedDecl **Def = nullptr) const; + /// A type is incomplete according to our definition iff: + /// - it is "incomplete" according to the standard definition; or + /// - it is sizeless (regardless of whether it's indefinite or definite) + /// + /// The intention is that the usual rules for incomplete types will + /// by default apply to sizeless types as well. Specifically-chosen + /// rules can then be redefined in terms of indefinite and definite if + /// definite sizeless types are acceptable. + bool isIncompleteType() const { + return isIndefiniteType() || isSizelessType(); + } /// Return true if this is an incomplete or object /// type, in other words, not a function type. @@ -2431,23 +2464,30 @@ #include "clang/Basic/OpenCLExtensionTypes.def" // All other builtin types #define BUILTIN_TYPE(Id, SingletonId) Id, -#define LAST_BUILTIN_TYPE(Id) LastKind = Id +#define LAST_BUILTIN_TYPE(Id) LastTIBuiltinType = Id, #include "clang/AST/BuiltinTypes.def" }; private: friend class ASTContext; // ASTContext creates these. - BuiltinType(Kind K) - : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), - /*InstantiationDependent=*/(K == Dependent), - /*VariablyModified=*/false, - /*Unexpanded parameter pack=*/false) { + BuiltinType(Kind K, llvm::Triple::ArchType T, int D) + : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), + /*InstantiationDependent=*/(K == Dependent), + /*VariablyModified=*/false, + /*Unexpanded parameter pack=*/false) { BuiltinTypeBits.Kind = K; + BuiltinTypeBits.Target = T; + BuiltinTypeBits.TargetDetail = D; } public: Kind getKind() const { return static_cast(BuiltinTypeBits.Kind); } + bool isTargetKind() const { return BuiltinTypeBits.Kind > LastTIBuiltinType; } + llvm::Triple::ArchType getTarget() const { + return static_cast(BuiltinTypeBits.Target); + } + int getTargetDetail() const { return BuiltinTypeBits.TargetDetail; } StringRef getName(const PrintingPolicy &Policy) const; const char *getNameAsCString(const PrintingPolicy &Policy) const { @@ -2485,6 +2525,11 @@ /// which cannot appear in arbitrary positions in a fully-formed /// expression. bool isPlaceholderType() const { + // Sizeless builtin types can appear in arbitrary positions in a + // fully-formed expression. + if (isSizelessBuiltinType()) + return false; + return isPlaceholderTypeKind(getKind()); } @@ -5110,9 +5155,10 @@ /// The "class" keyword. TTK_Class, - - /// The "enum" keyword. - TTK_Enum + /// \brief The "enum" keyword. + TTK_Enum, + /// \brief The "__sizeless_struct" keyword. + TTK_SizelessStruct }; /// The elaboration keyword that precedes a qualified type name or @@ -5120,8 +5166,10 @@ enum ElaboratedTypeKeyword { /// The "struct" keyword introduces the elaborated-type-specifier. ETK_Struct, - - /// The "__interface" keyword introduces the elaborated-type-specifier. + /// \brief The "__sizeless_struct" keyword introduces the + /// elaborated-type-specifier. + ETK_SizelessStruct, + /// \brief The "__interface" keyword introduces the elaborated-type-specifier. ETK_Interface, /// The "union" keyword introduces the elaborated-type-specifier. diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -853,7 +853,7 @@ AttributedType, AttributedLocInfo> { public: - attr::Kind getAttrKind() const { + AttributedType::Kind getAttrKind() const { return getTypePtr()->getAttrKind(); } diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2957,6 +2957,7 @@ def LoopHint : Attr { /// #pragma clang loop