diff options
Diffstat (limited to 'clang/include')
60 files changed, 1288 insertions, 251 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index b929585..be038d9 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -6953,7 +6953,7 @@ clang_getCursorUnaryOperatorKind(CXCursor cursor); * @} */ -CINDEX_DEPRECATED +/* CINDEX_DEPRECATED - disabled to silence MSVC deprecation warnings */ typedef void *CXRemapping; CINDEX_DEPRECATED CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *); diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 66ec339..3b98274a 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -238,9 +238,9 @@ class ASTContext : public RefCountedBase<ASTContext> { mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes{ GeneralTypesLog2InitSize}; mutable llvm::FoldingSet<DependentNameType> DependentNameTypes; - mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType, - ASTContext&> - DependentTemplateSpecializationTypes; + mutable llvm::DenseMap<llvm::FoldingSetNodeID, + DependentTemplateSpecializationType *> + DependentTemplateSpecializationTypes; mutable llvm::FoldingSet<PackExpansionType> PackExpansionTypes; mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes; mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes; @@ -277,6 +277,11 @@ class ASTContext : public RefCountedBase<ASTContext> { mutable llvm::ContextualFoldingSet<ArrayParameterType, ASTContext &> ArrayParameterTypes; + /// Store the unique Type corresponding to each Kind. + mutable std::array<Type *, + llvm::to_underlying(PredefinedSugarType::Kind::Last) + 1> + PredefinedSugarTypes{}; + /// The set of nested name specifiers. /// /// This set is managed by the NestedNameSpecifier class. @@ -1192,6 +1197,8 @@ public: bool isInSameModule(const Module *M1, const Module *M2) const; TranslationUnitDecl *getTranslationUnitDecl() const { + assert(TUDecl->getMostRecentDecl() == TUDecl && + "The active TU is not current one!"); return TUDecl->getMostRecentDecl(); } void addTranslationUnitDecl() { @@ -1567,6 +1574,8 @@ public: /// and bit count. QualType getDependentBitIntType(bool Unsigned, Expr *BitsExpr) const; + QualType getPredefinedSugarType(PredefinedSugarType::Kind KD) const; + /// Gets the struct used to keep track of the extended descriptor for /// pointer to blocks. QualType getBlockDescriptorExtendedType() const; @@ -1809,7 +1818,7 @@ public: NumPositiveBits = std::max({NumPositiveBits, ActiveBits, 1u}); } else { NumNegativeBits = - std::max(NumNegativeBits, (unsigned)InitVal.getSignificantBits()); + std::max(NumNegativeBits, InitVal.getSignificantBits()); } MembersRepresentableByInt &= isRepresentableIntegerValue(InitVal, IntTy); @@ -1999,11 +2008,13 @@ public: /// <stddef.h>. /// /// The sizeof operator requires this (C99 6.5.3.4p4). - CanQualType getSizeType() const; + QualType getSizeType() const; + + CanQualType getCanonicalSizeType() const; /// Return the unique signed counterpart of /// the integer type corresponding to size_t. - CanQualType getSignedSizeType() const; + QualType getSignedSizeType() const; /// Return the unique type for "intmax_t" (C99 7.18.1.5), defined in /// <stdint.h>. diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 523c032..6c124aa 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -57,6 +57,7 @@ namespace clang { class StringLiteral; class TargetInfo; class ValueDecl; + class WarnUnusedResultAttr; /// A simple array of base specifiers. typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; @@ -262,6 +263,12 @@ public: SourceRange &R1, SourceRange &R2, ASTContext &Ctx) const; + /// Returns the WarnUnusedResultAttr that is declared on the callee + /// or its return type declaration, together with a NamedDecl that + /// refers to the declaration the attribute is attached to. + static std::pair<const NamedDecl *, const WarnUnusedResultAttr *> + getUnusedResultAttrImpl(const Decl *Callee, QualType ReturnType); + /// isLValue - True if this expression is an "l-value" according to /// the rules of the current language. C and C++ give somewhat /// different rules for this concept, but in general, the result of @@ -3190,11 +3197,13 @@ public: /// type. QualType getCallReturnType(const ASTContext &Ctx) const; - /// Returns the WarnUnusedResultAttr that is either declared on the called - /// function, or its return type declaration, together with a NamedDecl that - /// refers to the declaration the attribute is attached onto. - std::pair<const NamedDecl *, const Attr *> - getUnusedResultAttr(const ASTContext &Ctx) const; + /// Returns the WarnUnusedResultAttr that is declared on the callee + /// or its return type declaration, together with a NamedDecl that + /// refers to the declaration the attribute is attached to. + std::pair<const NamedDecl *, const WarnUnusedResultAttr *> + getUnusedResultAttr(const ASTContext &Ctx) const { + return getUnusedResultAttrImpl(getCalleeDecl(), getCallReturnType(Ctx)); + } /// Returns true if this call expression should warn on unused results. bool hasUnusedResultAttr(const ASTContext &Ctx) const { diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h index 8210be3..b923230 100644 --- a/clang/include/clang/AST/ExprObjC.h +++ b/clang/include/clang/AST/ExprObjC.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_AST_EXPROBJC_H #define LLVM_CLANG_AST_EXPROBJC_H +#include "clang/AST/Attr.h" #include "clang/AST/ComputeDependence.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" @@ -1234,6 +1235,19 @@ public: /// of `instancetype` (in that case it's an expression type). QualType getCallReturnType(ASTContext &Ctx) const; + /// Returns the WarnUnusedResultAttr that is declared on the callee + /// or its return type declaration, together with a NamedDecl that + /// refers to the declaration the attribute is attached to. + std::pair<const NamedDecl *, const WarnUnusedResultAttr *> + getUnusedResultAttr(ASTContext &Ctx) const { + return getUnusedResultAttrImpl(getMethodDecl(), getCallReturnType(Ctx)); + } + + /// Returns true if this message send should warn on unused results. + bool hasUnusedResultAttr(ASTContext &Ctx) const { + return getUnusedResultAttr(Ctx).second != nullptr; + } + /// Source range of the receiver. SourceRange getReceiverRange() const; diff --git a/clang/include/clang/AST/FormatString.h b/clang/include/clang/AST/FormatString.h index 3560766..a284f2c 100644 --- a/clang/include/clang/AST/FormatString.h +++ b/clang/include/clang/AST/FormatString.h @@ -489,7 +489,8 @@ public: /// For a TypedefType QT, if it is a named integer type such as size_t, /// assign the appropriate value to LM and return true. - static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM); + static bool namedTypeToLengthModifier(ASTContext &Ctx, QualType QT, + LengthModifier &LM); }; } // end analyze_format_string namespace diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 519a811..62991d9 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1208,6 +1208,8 @@ DEF_TRAVERSE_TYPE(BitIntType, {}) DEF_TRAVERSE_TYPE(DependentBitIntType, { TRY_TO(TraverseStmt(T->getNumBitsExpr())); }) +DEF_TRAVERSE_TYPE(PredefinedSugarType, {}) + #undef DEF_TRAVERSE_TYPE // ----------------- TypeLoc traversal ----------------- @@ -1524,6 +1526,8 @@ DEF_TRAVERSE_TYPELOC(DependentBitIntType, { TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr())); }) +DEF_TRAVERSE_TYPELOC(PredefinedSugarType, {}) + #undef DEF_TRAVERSE_TYPELOC // ----------------- Decl traversal ----------------- diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 21b9710..98810fb 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2258,6 +2258,30 @@ protected: unsigned NumExpansions; }; + enum class PredefinedSugarKind { + /// The "size_t" type. + SizeT, + + /// The signed integer type corresponding to "size_t". + SignedSizeT, + + /// The "ptrdiff_t" type. + PtrdiffT, + + // Indicates how many items the enum has. + Last = PtrdiffT + }; + + class PresefinedSugarTypeBitfields { + friend class PredefinedSugarType; + + LLVM_PREFERRED_TYPE(TypeBitfields) + unsigned : NumTypeBits; + + LLVM_PREFERRED_TYPE(PredefinedSugarKind) + unsigned Kind : 8; + }; + class CountAttributedTypeBitfields { friend class CountAttributedType; @@ -2297,6 +2321,7 @@ protected: DependentTemplateSpecializationTypeBits; PackExpansionTypeBitfields PackExpansionTypeBits; CountAttributedTypeBitfields CountAttributedTypeBits; + PresefinedSugarTypeBitfields PredefinedSugarTypeBits; }; private: @@ -7251,8 +7276,7 @@ public: /// Represents a template specialization type whose template cannot be /// resolved, e.g. /// A<T>::template B<T> -class DependentTemplateSpecializationType : public TypeWithKeyword, - public llvm::FoldingSetNode { +class DependentTemplateSpecializationType : public TypeWithKeyword { friend class ASTContext; // ASTContext creates these DependentTemplateStorage Name; @@ -8038,6 +8062,37 @@ public: } }; +class PredefinedSugarType final : public Type { +public: + friend class ASTContext; + using Kind = PredefinedSugarKind; + +private: + PredefinedSugarType(Kind KD, const IdentifierInfo *IdentName, + QualType CanonicalType) + : Type(PredefinedSugar, CanonicalType, TypeDependence::None), + Name(IdentName) { + PredefinedSugarTypeBits.Kind = llvm::to_underlying(KD); + } + + static StringRef getName(Kind KD); + + const IdentifierInfo *Name; + +public: + bool isSugared() const { return true; } + + QualType desugar() const { return getCanonicalTypeInternal(); } + + Kind getKind() const { return Kind(PredefinedSugarTypeBits.Kind); } + + const IdentifierInfo *getIdentifier() const { return Name; } + + static bool classof(const Type *T) { + return T->getTypeClass() == PredefinedSugar; + } +}; + /// A qualifier set is used to build a set of qualifiers. class QualifierCollector : public Qualifiers { public: diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index cf06e27..be0bc89 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -2783,6 +2783,16 @@ public: } }; +struct PredefinedSugarTypeLocInfo {}; // Nothing. + +class PredefinedSugarTypeLoc final + : public ConcreteTypeLoc<UnqualTypeLoc, PredefinedSugarTypeLoc, + PredefinedSugarType, PredefinedSugarTypeLocInfo> { +public: + void initializeLocal(ASTContext &Context, SourceLocation loc) {} + SourceRange getLocalSourceRange() const { return {}; } +}; + } // namespace clang #endif // LLVM_CLANG_AST_TYPELOC_H diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index a615764..3114d11 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -1028,3 +1028,12 @@ let Class = DependentBitIntType in { return ctx.getDependentBitIntType(isUnsigned, numBitsExpr); }]>; } + +let Class = PredefinedSugarType in { + def : Property<"kind", UInt32> { + let Read = [{ static_cast<uint32_t>(node->getKind()) }]; + } + def : Creator<[{ + return ctx.getPredefinedSugarType(static_cast<PredefinedSugarType::Kind>(kind)); + }]>; +} diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h index 9998702..1c00558 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h @@ -17,14 +17,105 @@ //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H #define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H -#include "clang/AST/DeclBase.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Analysis/CFG.h" -namespace clang { +#include "llvm/ADT/ImmutableSet.h" +#include "llvm/ADT/StringMap.h" +#include <memory> -void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg, - AnalysisDeclContext &AC); +namespace clang::lifetimes { -} // namespace clang +/// The main entry point for the analysis. +void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC); + +namespace internal { +// Forward declarations of internal types. +class Fact; +class FactManager; +class LoanPropagationAnalysis; +class ExpiredLoansAnalysis; +struct LifetimeFactory; + +/// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type. +/// Used for giving ID to loans and origins. +template <typename Tag> struct ID { + uint32_t Value = 0; + + bool operator==(const ID<Tag> &Other) const { return Value == Other.Value; } + bool operator!=(const ID<Tag> &Other) const { return !(*this == Other); } + bool operator<(const ID<Tag> &Other) const { return Value < Other.Value; } + ID<Tag> operator++(int) { + ID<Tag> Tmp = *this; + ++Value; + return Tmp; + } + void Profile(llvm::FoldingSetNodeID &IDBuilder) const { + IDBuilder.AddInteger(Value); + } +}; +template <typename Tag> +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, ID<Tag> ID) { + return OS << ID.Value; +} + +using LoanID = ID<struct LoanTag>; +using OriginID = ID<struct OriginTag>; + +// Using LLVM's immutable collections is efficient for dataflow analysis +// as it avoids deep copies during state transitions. +// TODO(opt): Consider using a bitset to represent the set of loans. +using LoanSet = llvm::ImmutableSet<LoanID>; +using OriginSet = llvm::ImmutableSet<OriginID>; + +/// A `ProgramPoint` identifies a location in the CFG by pointing to a specific +/// `Fact`. identified by a lifetime-related event (`Fact`). +/// +/// A `ProgramPoint` has "after" semantics: it represents the location +/// immediately after its corresponding `Fact`. +using ProgramPoint = const Fact *; + +/// Running the lifetime safety analysis and querying its results. It +/// encapsulates the various dataflow analyses. +class LifetimeSafetyAnalysis { +public: + LifetimeSafetyAnalysis(AnalysisDeclContext &AC); + ~LifetimeSafetyAnalysis(); + + void run(); + + /// Returns the set of loans an origin holds at a specific program point. + LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const; + + /// Returns the set of loans that have expired at a specific program point. + LoanSet getExpiredLoansAtPoint(ProgramPoint PP) const; + + /// Finds the OriginID for a given declaration. + /// Returns a null optional if not found. + std::optional<OriginID> getOriginIDForDecl(const ValueDecl *D) const; + + /// Finds the LoanID's for the loan created with the specific variable as + /// their Path. + std::vector<LoanID> getLoanIDForVar(const VarDecl *VD) const; + + /// Retrieves program points that were specially marked in the source code + /// for testing. + /// + /// The analysis recognizes special function calls of the form + /// `void("__lifetime_test_point_<name>")` as test points. This method returns + /// a map from the annotation string (<name>) to the corresponding + /// `ProgramPoint`. This allows test harnesses to query the analysis state at + /// user-defined locations in the code. + /// \note This is intended for testing only. + llvm::StringMap<ProgramPoint> getTestPoints() const; + +private: + AnalysisDeclContext &AC; + std::unique_ptr<LifetimeFactory> Factory; + std::unique_ptr<FactManager> FactMgr; + std::unique_ptr<LoanPropagationAnalysis> LoanPropagation; + std::unique_ptr<ExpiredLoansAnalysis> ExpiredLoans; +}; +} // namespace internal +} // namespace clang::lifetimes #endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index fefdaba..76747d2 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -9417,9 +9417,9 @@ def NonStringDocs : Documentation { let Category = DocCatDecl; let Content = [{ The ``nonstring`` attribute can be applied to the declaration of a variable or -a field whose type is a character array to specify that the character array is -not intended to behave like a null-terminated string. This will silence -diagnostics with code like: +a field whose type is a character pointer or character array to specify that +the buffer is not intended to behave like a null-terminated string. This will +silence diagnostics with code like: .. code-block:: c diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 5ebb821..c81714e 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -1334,6 +1334,18 @@ def ElementwiseMinimum : Builtin { let Prototype = "void(...)"; } +def ElementwiseMaximumNum : Builtin { + let Spellings = ["__builtin_elementwise_maximumnum"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseMinimumNum : Builtin { + let Spellings = ["__builtin_elementwise_minimumnum"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + def ElementwiseCeil : Builtin { let Spellings = ["__builtin_elementwise_ceil"]; let Attributes = [NoThrow, Const, CustomTypeChecking]; diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index a916af7..172ac46 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -642,6 +642,26 @@ TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_f16_f32, "V2hV2hfUiIb", "nc", "f32-to-f16 // GFX1250+ only builtins. //===----------------------------------------------------------------------===// +TARGET_BUILTIN(__builtin_amdgcn_flat_prefetch, "vvC*0Ii", "nc", "vmem-pref-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_prefetch, "vvC*1Ii", "nc", "vmem-pref-insts") + +TARGET_BUILTIN(__builtin_amdgcn_global_load_monitor_b32, "ii*1Ii", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_load_monitor_b64, "V2iV2i*1Ii", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_load_monitor_b128, "V4iV4i*1Ii", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_flat_load_monitor_b32, "ii*0Ii", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_flat_load_monitor_b64, "V2iV2i*0Ii", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_flat_load_monitor_b128, "V4iV4i*0Ii", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_load_async_to_lds_b8, "vc*1c*3IiIi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_load_async_to_lds_b32, "vi*1i*3IiIi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_load_async_to_lds_b64, "vV2i*1V2i*3IiIi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_load_async_to_lds_b128, "vV4i*1V4i*3IiIi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_store_async_from_lds_b8, "vc*1c*3IiIi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_store_async_from_lds_b32, "vi*1i*3IiIi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_store_async_from_lds_b64, "vV2i*1V2i*3IiIi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_store_async_from_lds_b128, "vV4i*1V4i*3IiIi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_async_barrier_arrive_b64, "vLi*3", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_barrier_arrive_rtn_b64, "LiLi*3Li", "nc", "gfx1250-insts") + TARGET_BUILTIN(__builtin_amdgcn_tensor_load_to_lds, "vV4iV8iV4iV4iIi", "nc", "gfx1250-insts") TARGET_BUILTIN(__builtin_amdgcn_tensor_load_to_lds_d2, "vV4iV8iIi", "nc", "gfx1250-insts") TARGET_BUILTIN(__builtin_amdgcn_tensor_store_from_lds, "vV4iV8iV4iV4iIi", "nc", "gfx1250-insts") @@ -660,9 +680,6 @@ TARGET_BUILTIN(__builtin_amdgcn_ds_load_tr16_b128_v8i16, "V8sV8s*3", "nc", "gfx1 TARGET_BUILTIN(__builtin_amdgcn_ds_load_tr16_b128_v8f16, "V8hV8h*3", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_ds_load_tr16_b128_v8bf16, "V8yV8y*3", "nc", "gfx1250-insts,wavefrontsize32") -TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_async_barrier_arrive_b64, "vLi*3", "nc", "gfx1250-insts") -TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_barrier_arrive_rtn_b64, "LiLi*3Li", "nc", "gfx1250-insts") - TARGET_BUILTIN(__builtin_amdgcn_s_setprio_inc_wg, "vIs", "n", "setprio-inc-wg-inst") TARGET_BUILTIN(__builtin_amdgcn_s_monitor_sleep, "vIs", "n", "gfx1250-insts") @@ -680,10 +697,17 @@ TARGET_BUILTIN(__builtin_amdgcn_exp2_bf16, "yy", "nc", "bf16-trans-insts") TARGET_BUILTIN(__builtin_amdgcn_sin_bf16, "yy", "nc", "bf16-trans-insts") TARGET_BUILTIN(__builtin_amdgcn_cos_bf16, "yy", "nc", "bf16-trans-insts") +TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_pk_bf16_f32, "V2yffi", "nc", "bf16-cvt-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_f16_fp8, "hiIi", "nc", "gfx1250-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_f16_bf8, "hiIi", "nc", "gfx1250-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_f16_fp8, "V2hs", "nc", "gfx1250-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_f16_bf8, "V2hs", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_fp8_f16, "sV2h", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_bf8_f16, "sV2h", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_fp8_f16, "ihiUiIi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_bf8_f16, "ihiUiIi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_sat_pk4_i4_i8, "UsUi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_sat_pk4_u4_u8, "UsUi", "nc", "gfx1250-insts") // GFX1250 WMMA builtins TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x4_f32, "V8fIbV2fIbV2fIsV8fIbIb", "nc", "gfx1250-insts,wavefrontsize32") @@ -703,6 +727,7 @@ TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x128_fp8_fp8, "V8hV16iV16iIsV8hIbI TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x128_fp8_bf8, "V8hV16iV16iIsV8hIbIb", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x128_bf8_fp8, "V8hV16iV16iIsV8hIbIb", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x128_bf8_bf8, "V8hV16iV16iIsV8hIbIb", "nc", "gfx1250-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x128_f8f6f4, "V8fIiV16iIiV16iIsV8f", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x128_fp8_fp8, "V8fV16iV16iIsV8fIbIb", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x128_fp8_bf8, "V8fV16iV16iIsV8fIbIb", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x128_bf8_fp8, "V8fV16iV16iIsV8fIbIb", "nc", "gfx1250-insts,wavefrontsize32") diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index e2afcc0..d31b726 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -199,6 +199,12 @@ TARGET_BUILTIN(__builtin_wasm_ref_is_null_extern, "ii", "nct", "reference-types" // return type. TARGET_BUILTIN(__builtin_wasm_ref_null_func, "i", "nct", "reference-types") +// Check if the runtime type of a function pointer matches its static type. Used +// to avoid "function signature mismatch" traps. Takes a function pointer, uses +// table.get to look up the pointer in __indirect_function_table and then +// ref.test to test the type. +TARGET_BUILTIN(__builtin_wasm_test_function_pointer_signature, "i.", "nct", "gc") + // Table builtins TARGET_BUILTIN(__builtin_wasm_table_set, "viii", "t", "reference-types") TARGET_BUILTIN(__builtin_wasm_table_get, "iii", "t", "reference-types") diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index cfffeb7..423b696 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -307,15 +307,17 @@ CODEGENOPT(SanitizeBinaryMetadataAtomics, 1, 0, Benign) ///< Emit PCs for atomic CODEGENOPT(SanitizeBinaryMetadataUAR, 1, 0, Benign) ///< Emit PCs for start of functions ///< that are subject for use-after-return checking. CODEGENOPT(SanitizeStats , 1, 0, Benign) ///< Collect statistics for sanitizers. +CODEGENOPT(SanitizeDebugTrapReasons, 1, 1 , Benign) ///< Enable UBSan trapping messages CODEGENOPT(SimplifyLibCalls , 1, 1, Benign) ///< Set when -fbuiltin is enabled. CODEGENOPT(SoftFloat , 1, 0, Benign) ///< -soft-float. CODEGENOPT(SpeculativeLoadHardening, 1, 0, Benign) ///< Enable speculative load hardening. CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0, Benign) ///< Enable fine-grained bitfield accesses. CODEGENOPT(StrictEnums , 1, 0, Benign) ///< Optimize based on strict enum definition. CODEGENOPT(StrictVTablePointers, 1, 0, Benign) ///< Optimize based on the strict vtable pointers -CODEGENOPT(TimePasses , 1, 0, Benign) ///< Set when -ftime-report or -ftime-report= or -ftime-report-json is enabled. +CODEGENOPT(TimePasses , 1, 0, Benign) ///< Set when -ftime-report, -ftime-report=, -ftime-report-json, or -stats-file-timers is enabled. CODEGENOPT(TimePassesPerRun , 1, 0, Benign) ///< Set when -ftime-report=per-pass-run is enabled. CODEGENOPT(TimePassesJson , 1, 0, Benign) ///< Set when -ftime-report-json is enabled. +CODEGENOPT(TimePassesStatsFile , 1, 0, Benign) ///< Set when -stats-file-timers is enabled. CODEGENOPT(TimeTrace , 1, 0, Benign) ///< Set when -ftime-trace is enabled. VALUE_CODEGENOPT(TimeTraceGranularity, 32, 500, Benign) ///< Minimum time granularity (in microseconds), ///< traced by time profiler diff --git a/clang/include/clang/Basic/CustomizableOptional.h b/clang/include/clang/Basic/CustomizableOptional.h index 2d6ae6a..8559eaa 100644 --- a/clang/include/clang/Basic/CustomizableOptional.h +++ b/clang/include/clang/Basic/CustomizableOptional.h @@ -70,15 +70,6 @@ public: void reset() { Storage.reset(); } - LLVM_DEPRECATED("Use &*X instead.", "&*X") - constexpr const T *getPointer() const { return &Storage.value(); } - LLVM_DEPRECATED("Use &*X instead.", "&*X") - T *getPointer() { return &Storage.value(); } - LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") - constexpr const T &value() const & { return Storage.value(); } - LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") - T &value() & { return Storage.value(); } - constexpr explicit operator bool() const { return has_value(); } constexpr bool has_value() const { return Storage.has_value(); } constexpr const T *operator->() const { return &Storage.value(); } @@ -90,8 +81,6 @@ public: return has_value() ? operator*() : std::forward<U>(alt); } - LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") - T &&value() && { return std::move(Storage.value()); } T &&operator*() && { return std::move(Storage.value()); } template <typename U> T value_or(U &&alt) && { diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index c7a6276..cee5bed 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -895,7 +895,10 @@ public: /// \param FormatString A fixed diagnostic format string that will be hashed /// and mapped to a unique DiagID. template <unsigned N> - // TODO: Deprecate this once all uses are removed from Clang. + // FIXME: this API should almost never be used; custom diagnostics do not + // have an associated diagnostic group and thus cannot be controlled by users + // like other diagnostics. The number of times this API is used in Clang + // should only ever be reduced, not increased. // [[deprecated("Use a CustomDiagDesc instead of a Level")]] unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) { return Diags->getCustomDiagID((DiagnosticIDs::Level)L, diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index 071a38f..46d04b0 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -511,6 +511,14 @@ def note_odr_number_of_bases : Note< "class has %0 base %plural{1:class|:classes}0">; def note_odr_enumerator : Note<"enumerator %0 with value %1 here">; def note_odr_missing_enumerator : Note<"no corresponding enumerator here">; +def note_odr_incompatible_fixed_underlying_type : Note< + "enumeration %0 declared with incompatible fixed underlying types (%1 vs. " + "%2)">; +def note_odr_fixed_underlying_type : Note< + "enumeration %0 has fixed underlying type here">; +def note_odr_missing_fixed_underlying_type : Note< + "enumeration %0 missing fixed underlying type here">; + def err_odr_field_type_inconsistent : Error< "field %0 declared with incompatible types in different " "translation units (%1 vs. %2)">; diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 34b6c0d..759ba04 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -116,6 +116,8 @@ def err_drv_cuda_host_arch : Error< "unsupported architecture '%0' for host compilation">; def err_drv_mix_cuda_hip : Error< "mixed CUDA and HIP compilation is not supported">; +def err_drv_mix_offload : Error< + "mixed %0 and %1 offloading compilation is not supported">; def err_drv_bad_target_id : Error< "invalid target ID '%0'; format is a processor name followed by an optional " "colon-delimited list of features followed by an enable/disable sign (e.g., " diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h index 2b095f0..f07a003 100644 --- a/clang/include/clang/Basic/DiagnosticIDs.h +++ b/clang/include/clang/Basic/DiagnosticIDs.h @@ -283,7 +283,10 @@ public: // writing, nearly all callers of this function were invalid. unsigned getCustomDiagID(CustomDiagDesc Diag); - // TODO: Deprecate this once all uses are removed from LLVM + // FIXME: this API should almost never be used; custom diagnostics do not + // have an associated diagnostic group and thus cannot be controlled by users + // like other diagnostics. The number of times this API is used in Clang + // should only ever be reduced, not increased. // [[deprecated("Use a CustomDiagDesc instead of a Level")]] unsigned getCustomDiagID(Level Level, StringRef Message) { return getCustomDiagID([&]() -> CustomDiagDesc { diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 723f5d4..c7fe6e1d 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -694,6 +694,9 @@ def err_pragma_push_pop_macro_malformed : Error< def warn_pragma_pop_macro_no_push : Warning< "pragma pop_macro could not pop '%0', no matching push_macro">, InGroup<IgnoredPragmas>; +def warn_pargma_push_pop_macro_empty_string : Warning< + "'#pragma %select{push_macro|pop_macro}0' expected a non-empty string">, + InGroup<IgnoredPragmas>; def warn_pragma_message : Warning<"%0">, InGroup<PoundPragmaMessage>, DefaultWarnNoWerror; def err_pragma_message : Error<"%0">; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 35903af..165f015 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1594,6 +1594,9 @@ def err_omp_unknown_adjust_args_op def err_omp_declare_variant_wrong_clause : Error< "expected %select{'match'|'match', 'adjust_args', or 'append_args'}0 clause " "on 'omp declare variant' directive">; +def err_omp_non_by_ref_need_device_addr_modifier_argument + : Error<"expected reference type argument on 'adjust_args' clause with " + "'need_device_addr' modifier">; def err_omp_declare_variant_duplicate_nested_trait : Error< "nested OpenMP context selector contains duplicated trait '%0'" " in selector '%1' and set '%2' with different score">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b2ea65a..27d2152 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1812,10 +1812,7 @@ def note_unsatisfied_trait_reason "%DeletedAssign{has a deleted %select{copy|move}1 " "assignment operator}|" "%UnionWithUserDeclaredSMF{is a union with a user-declared " - "%sub{select_special_member_kind}1}|" - "%FunctionType{is a function type}|" - "%CVVoidType{is a cv void type}|" - "%IncompleteArrayType{is an incomplete array type}" + "%sub{select_special_member_kind}1}" "}0">; def warn_consteval_if_always_true : Warning< @@ -7575,6 +7572,8 @@ def err_typecheck_illegal_increment_decrement : Error< "cannot %select{decrement|increment}1 value of type %0">; def err_typecheck_expect_int : Error< "used type %0 where integer is required">; +def err_typecheck_expect_function_pointer + : Error<"used type %0 where function pointer is required">; def err_typecheck_expect_hlsl_resource : Error< "used type %0 where __hlsl_resource_t is required">; def err_typecheck_arithmetic_incomplete_or_sizeless_type : Error< @@ -9329,8 +9328,28 @@ def err_atomic_builtin_pointer_size : Error< "address argument to atomic builtin must be a pointer to 1,2,4,8 or 16 byte " "type (%0 invalid)">; def err_atomic_exclusive_builtin_pointer_size : Error< - "address argument to load or store exclusive builtin must be a pointer to" - " 1,2,4 or 8 byte type (%0 invalid)">; + "address argument to load or store exclusive builtin must be a pointer to " + // Because the range of legal sizes for load/store exclusive varies with the + // Arm architecture version, this error message wants to be able to specify + // various different subsets of the sizes 1, 2, 4, 8. Rather than make a + // separate diagnostic for each subset, I've arranged here that _this_ error + // can display any combination of the sizes. For each size there are two + // %select parameters: the first chooses whether you need a "," or " or " to + // separate the number from a previous one (or neither), and the second + // parameter indicates whether to display the number itself. + // + // (The very first of these parameters isn't really necessary, since you + // never want to start with "," or " or " before the first number in the + // list, but it keeps it simple to make it look exactly like the other cases, + // and also allows a loop constructing this diagnostic to handle every case + // exactly the same.) + "%select{|,| or }1%select{|1}2" + "%select{|,| or }3%select{|2}4" + "%select{|,| or }5%select{|4}6" + "%select{|,| or }7%select{|8}8" + " byte type (%0 invalid)">; +def err_atomic_exclusive_builtin_pointer_size_none : Error< + "load and store exclusive builtins are not available on this architecture">; def err_atomic_builtin_ext_int_size : Error< "atomic memory operand must have a power-of-two size">; def err_atomic_builtin_bit_int_prohibit : Error< @@ -12389,6 +12408,13 @@ def err_invalid_module_name : Error<"%0 is an invalid name for a module">; def err_extern_def_in_header_unit : Error< "non-inline external definitions are not permitted in C++ header units">; +def warn_exposure : Warning < + "TU local entity %0 is exposed">, + InGroup<DiagGroup<"TU-local-entity-exposure">>; +def warn_reference_tu_local_entity_in_other_tu : Warning < + "instantiation of %0 triggers reference to TU-local entity %1 from other TU '%2'">, + InGroup<DiagGroup<"reference-tu-local-entity-in-other-tu">>; + def warn_experimental_header_unit : Warning< "the implementation of header units is in an experimental phase">, InGroup<DiagGroup<"experimental-header-units">>; @@ -13202,6 +13228,10 @@ def err_wasm_builtin_arg_must_match_table_element_type : Error < "%ordinal0 argument must match the element type of the WebAssembly table in the %ordinal1 argument">; def err_wasm_builtin_arg_must_be_integer_type : Error < "%ordinal0 argument must be an integer">; +def err_wasm_builtin_test_fp_sig_cannot_include_reference_type + : Error<"not supported for " + "function pointers with a reference type %select{return " + "value|parameter}0">; // OpenACC diagnostics. def warn_acc_routine_unimplemented @@ -13257,6 +13287,11 @@ def err_acc_not_a_var_ref def err_acc_not_a_var_ref_use_device_declare : Error<"OpenACC variable %select{in 'use_device' clause|on 'declare' " "construct}0 is not a valid variable name or array name">; +def ext_acc_array_section_use_device_declare + : Extension< + "sub-array as a variable %select{in 'use_device' clause|on " + "'declare' construct}0 is not a valid variable name or array name">, + InGroup<DiagGroup<"openacc-extension">>; def err_acc_not_a_var_ref_cache : Error<"OpenACC variable in 'cache' directive is not a valid sub-array or " "array element">; @@ -13318,8 +13353,9 @@ def err_acc_reduction_num_gangs_conflict "appear on a '%2' construct " "with a '%3' clause%select{ with more than 1 argument|}0">; def err_acc_reduction_type - : Error<"OpenACC 'reduction' variable must be of scalar type, sub-array, or a " - "composite of scalar types;%select{| sub-array base}1 type is %0">; + : Error<"OpenACC 'reduction' variable must be of scalar type, aggregate, " + "sub-array, or a composite of scalar types;%select{| sub-array " + "base}1 type is %0">; def err_acc_reduction_composite_type : Error<"OpenACC 'reduction' variable must be a composite of scalar types; " "%1 %select{is not a class or struct|is incomplete|is not an " @@ -13438,13 +13474,13 @@ def note_acc_atomic_mismatch_operand : Note<"left hand side of assignment operation(%0) must match one side " "of the sub-operation on the right hand side(%1 and %2)">; def note_acc_atomic_mismatch_compound_operand - : Note<"variable %select{|in unary expression|on right hand side of " + : Note<"sub-expression %select{|in unary expression|on right hand side of " "assignment|on left hand side of assignment|on left hand side of " "compound assignment|on left hand side of assignment}2(%3) must " - "match variable used %select{|in unary expression|on right hand " - "side of assignment|<not possible>|on left hand side of compound " - "assignment|on left hand side of assignment}0(%1) from the first " - "statement">; + "match sub-expression used %select{|in unary expression|on right " + "hand side of assignment|<not possible>|on left hand side of " + "compound assignment|on left hand side of assignment}0(%1) from the " + "first statement">; def err_acc_declare_required_clauses : Error<"no valid clauses specified in OpenACC 'declare' directive">; def err_acc_declare_clause_at_global diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h index e83a61d..337911e 100644 --- a/clang/include/clang/Basic/FileManager.h +++ b/clang/include/clang/Basic/FileManager.h @@ -237,11 +237,6 @@ public: FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size, time_t ModificationTime); - LLVM_DEPRECATED("Functions returning FileEntry are deprecated.", - "getVirtualFileRef()") - const FileEntry *getVirtualFile(StringRef Filename, off_t Size, - time_t ModificationTime); - /// Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual /// file entry, to access the real file. The returned FileEntry will have /// the same filename as FE but a different identity and its own stat. diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 6ac8d49..08d98a7 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -491,6 +491,8 @@ LANGOPT(CheckConstexprFunctionBodies, 1, 1, Benign, LANGOPT(BoundsSafety, 1, 0, NotCompatible, "Bounds safety extension for C") +LANGOPT(EnableLifetimeSafety, 1, 0, NotCompatible, "Experimental lifetime safety analysis for C++") + LANGOPT(PreserveVec3Type, 1, 0, NotCompatible, "Preserve 3-component vector type") #undef LANGOPT diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h index 698fd9d..005f261 100644 --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -120,7 +120,7 @@ namespace clang { /// A C++ access specifier (public, private, protected), plus the /// special value "none" which means different things in different contexts. - enum AccessSpecifier { + enum AccessSpecifier : uint8_t { AS_public, AS_protected, AS_private, diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 8b66c73..ce4677e 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1071,6 +1071,17 @@ public: /// as Custom Datapath. uint32_t getARMCDECoprocMask() const { return ARMCDECoprocMask; } + /// For ARM targets returns a mask defining which data sizes are suitable for + /// __builtin_arm_ldrex and __builtin_arm_strex. + enum { + ARM_LDREX_B = (1 << 0), /// byte (8-bit) + ARM_LDREX_H = (1 << 1), /// half (16-bit) + ARM_LDREX_W = (1 << 2), /// word (32-bit) + ARM_LDREX_D = (1 << 3), /// double (64-bit) + }; + + virtual unsigned getARMLDREXMask() const { return 0; } + /// Returns whether the passed in string is a valid clobber in an /// inline asm statement. /// @@ -1551,8 +1562,8 @@ public: // Return the target-specific priority for features/cpus/vendors so // that they can be properly sorted for checking. - virtual uint64_t getFMVPriority(ArrayRef<StringRef> Features) const { - return 0; + virtual llvm::APInt getFMVPriority(ArrayRef<StringRef> Features) const { + return llvm::APInt::getZero(32); } // Validate the contents of the __builtin_cpu_is(const char*) diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td index 567b8a5..971ce54 100644 --- a/clang/include/clang/Basic/TypeNodes.td +++ b/clang/include/clang/Basic/TypeNodes.td @@ -117,3 +117,4 @@ def PipeType : TypeNode<Type>; def AtomicType : TypeNode<Type>; def BitIntType : TypeNode<Type>; def DependentBitIntType : TypeNode<Type>, AlwaysDependent; +def PredefinedSugarType : TypeNode<Type>, NeverCanonical; diff --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td index 0daef4a..ef19610 100644 --- a/clang/include/clang/Basic/arm_neon.td +++ b/clang/include/clang/Basic/arm_neon.td @@ -964,11 +964,11 @@ def SLI_N : WInst<"vsli_n", "...I", "PlQPl", [ImmCheck<2, ImmCheckShiftLeft, 0>] // Right shift narrow high def SHRN_HIGH_N : IOpInst<"vshrn_high_n", "<(<q).I", "HsHiHlHUsHUiHUl", OP_NARROW_HI>; -def QSHRUN_HIGH_N : SOpInst<"vqshrun_high_n", "<(<q).I", +def QSHRUN_HIGH_N : SOpInst<"vqshrun_high_n", "(<U)(<Uq).I", "HsHiHl", OP_NARROW_HI>; def RSHRN_HIGH_N : IOpInst<"vrshrn_high_n", "<(<q).I", "HsHiHlHUsHUiHUl", OP_NARROW_HI>; -def QRSHRUN_HIGH_N : SOpInst<"vqrshrun_high_n", "<(<q).I", +def QRSHRUN_HIGH_N : SOpInst<"vqrshrun_high_n", "(<U)(<Uq).I", "HsHiHl", OP_NARROW_HI>; def QSHRN_HIGH_N : SOpInst<"vqshrn_high_n", "<(<q).I", "HsHiHlHUsHUiHUl", OP_NARROW_HI>; diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 25baf27..b26e558 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -75,6 +75,18 @@ public: return getConstant(loc, cir::IntAttr::get(ty, value)); } + mlir::Value getSignedInt(mlir::Location loc, int64_t val, unsigned numBits) { + auto type = cir::IntType::get(getContext(), numBits, /*isSigned=*/true); + return getConstAPInt(loc, type, + llvm::APInt(numBits, val, /*isSigned=*/true)); + } + + mlir::Value getUnsignedInt(mlir::Location loc, uint64_t val, + unsigned numBits) { + auto type = cir::IntType::get(getContext(), numBits, /*isSigned=*/false); + return getConstAPInt(loc, type, llvm::APInt(numBits, val)); + } + // Creates constant null value for integral type ty. cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc) { return getConstant(loc, getZeroInitAttr(ty)); @@ -435,6 +447,10 @@ public: return create<cir::CmpOp>(loc, getBoolTy(), kind, lhs, rhs); } + mlir::Value createIsNaN(mlir::Location loc, mlir::Value operand) { + return createCompare(loc, cir::CmpOpKind::ne, operand, operand); + } + mlir::Value createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, bool isShiftLeft) { return create<cir::ShiftOp>(loc, lhs.getType(), lhs, rhs, isShiftLeft); diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 29d8aea..588fb0d 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -42,7 +42,7 @@ class CIR_TypedAttr<string name, string attrMnemonic, list<Trait> traits = []> let assemblyFormat = [{}]; } -class CIRUnitAttr<string name, string attrMnemonic, list<Trait> traits = []> +class CIR_UnitAttr<string name, string attrMnemonic, list<Trait> traits = []> : CIR_Attr<name, attrMnemonic, traits> { let returnType = "bool"; let defaultValue = "false"; @@ -127,7 +127,7 @@ def CIR_BoolAttr : CIR_Attr<"Bool", "bool", [TypedAttrInterface]> { // ZeroAttr //===----------------------------------------------------------------------===// -def ZeroAttr : CIR_TypedAttr<"Zero", "zero"> { +def CIR_ZeroAttr : CIR_TypedAttr<"Zero", "zero"> { let summary = "Attribute to represent zero initialization"; let description = [{ The ZeroAttr is used to indicate zero initialization on structs. @@ -138,7 +138,7 @@ def ZeroAttr : CIR_TypedAttr<"Zero", "zero"> { // UndefAttr //===----------------------------------------------------------------------===// -def UndefAttr : CIR_TypedAttr<"Undef", "undef"> { +def CIR_UndefAttr : CIR_TypedAttr<"Undef", "undef"> { let summary = "Represent an undef constant"; let description = [{ The UndefAttr represents an undef constant, corresponding to LLVM's notion @@ -147,6 +147,18 @@ def UndefAttr : CIR_TypedAttr<"Undef", "undef"> { } //===----------------------------------------------------------------------===// +// PoisonAttr +//===----------------------------------------------------------------------===// + +def CIR_PoisonAttr : CIR_TypedAttr<"Poison", "poison"> { + let summary = "Represent a typed poison constant"; + let description = [{ + The PoisonAttr represents a typed poison constant, corresponding to LLVM's + notion of poison. + }]; +} + +//===----------------------------------------------------------------------===// // IntegerAttr //===----------------------------------------------------------------------===// @@ -252,7 +264,9 @@ def CIR_FPAttr : CIR_Attr<"FP", "fp", [TypedAttrInterface]> { // ConstArrayAttr //===----------------------------------------------------------------------===// -def ConstArrayAttr : CIR_Attr<"ConstArray", "const_array", [TypedAttrInterface]> { +def CIR_ConstArrayAttr : CIR_Attr<"ConstArray", "const_array", [ + TypedAttrInterface +]> { let summary = "A constant array from ArrayAttr or StringRefAttr"; let description = [{ An CIR array attribute is an array of literals of the specified attr types. @@ -298,8 +312,9 @@ def ConstArrayAttr : CIR_Attr<"ConstArray", "const_array", [TypedAttrInterface]> // ConstVectorAttr //===----------------------------------------------------------------------===// -def ConstVectorAttr : CIR_Attr<"ConstVector", "const_vector", - [TypedAttrInterface]> { +def CIR_ConstVectorAttr : CIR_Attr<"ConstVector", "const_vector", [ + TypedAttrInterface +]> { let summary = "A constant vector from ArrayAttr"; let description = [{ A CIR vector attribute is an array of literals of the specified attribute @@ -330,7 +345,7 @@ def ConstVectorAttr : CIR_Attr<"ConstVector", "const_vector", // ConstPtrAttr //===----------------------------------------------------------------------===// -def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> { +def CIR_ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> { let summary = "Holds a constant pointer value"; let parameters = (ins AttributeSelfTypeParameter<"", "::cir::PointerType">:$type, @@ -359,8 +374,9 @@ def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> { // ConstComplexAttr //===----------------------------------------------------------------------===// -def ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex", - [TypedAttrInterface]> { +def CIR_ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex", [ + TypedAttrInterface +]> { let summary = "An attribute that contains a constant complex value"; let description = [{ The `#cir.const_complex` attribute contains a constant value of complex @@ -442,7 +458,7 @@ def CIR_VisibilityAttr : CIR_EnumAttr<CIR_VisibilityKind, "visibility"> { // BitfieldInfoAttr //===----------------------------------------------------------------------===// -def BitfieldInfoAttr : CIR_Attr<"BitfieldInfo", "bitfield_info"> { +def CIR_BitfieldInfoAttr : CIR_Attr<"BitfieldInfo", "bitfield_info"> { let summary = "Represents info for a bit-field member"; let description = [{ Holds the following information about bitfields: name, storage type, size @@ -500,5 +516,4 @@ def BitfieldInfoAttr : CIR_Attr<"BitfieldInfo", "bitfield_info"> { ]; } - #endif // CLANG_CIR_DIALECT_IR_CIRATTRS_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index d19cd83..5ef5b60 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -128,12 +128,12 @@ def CIR_CastKind : CIR_I32EnumAttr<"CastKind", "cast kind", [ // CK_BlockPointerToObjCPointerCast // CK_AnyPointerToBlockPointerCast // CK_ObjCObjectLValueCast - // I32EnumAttrCase<"float_to_complex", 44>, - // I32EnumAttrCase<"float_complex_to_real", 45>, - // I32EnumAttrCase<"float_complex_to_bool", 46>, + I32EnumAttrCase<"float_to_complex", 44>, + I32EnumAttrCase<"float_complex_to_real", 45>, + I32EnumAttrCase<"float_complex_to_bool", 46>, I32EnumAttrCase<"float_complex", 47>, - // I32EnumAttrCase<"float_complex_to_int_complex", 48>, - // I32EnumAttrCase<"int_to_complex", 49>, + I32EnumAttrCase<"float_complex_to_int_complex", 48>, + I32EnumAttrCase<"int_to_complex", 49>, I32EnumAttrCase<"int_complex_to_real", 50>, I32EnumAttrCase<"int_complex_to_bool", 51>, I32EnumAttrCase<"int_complex", 52>, @@ -607,8 +607,8 @@ def CIR_ConditionOp : CIR_Op<"condition", [ //===----------------------------------------------------------------------===// defvar CIR_YieldableScopes = [ - "CaseOp", "DoWhileOp", "ForOp", "IfOp", "ScopeOp", "SwitchOp", - "TernaryOp", "WhileOp" + "ArrayCtor", "ArrayDtor", "CaseOp", "DoWhileOp", "ForOp", "IfOp", "ScopeOp", + "SwitchOp", "TernaryOp", "WhileOp" ]; def CIR_YieldOp : CIR_Op<"yield", [ @@ -1739,20 +1739,24 @@ def CIR_SetBitfieldOp : CIR_Op<"set_bitfield"> { %2 = cir.load %0 : !cir.ptr<!cir.ptr<!record_type>>, !cir.ptr<!record_type> %3 = cir.get_member %2[1] {name = "e"} : !cir.ptr<!record_type> -> !cir.ptr<!u16i> - %4 = cir.set_bitfield(#bfi_e, %3 : !cir.ptr<!u16i>, %1 : !s32i) -> !s32i + %4 = cir.set_bitfield align(4) (#bfi_e, %3 : !cir.ptr<!u16i>, %1 : !s32i) + -> !s32i ``` }]; let arguments = (ins Arg<CIR_PointerType, "the address to store the value", [MemWrite]>:$addr, CIR_AnyType:$src, - BitfieldInfoAttr:$bitfield_info, + CIR_BitfieldInfoAttr:$bitfield_info, + DefaultValuedOptionalAttr<I64Attr, "0">:$alignment, UnitAttr:$is_volatile ); let results = (outs CIR_IntType:$result); - let assemblyFormat = [{ `(`$bitfield_info`,` $addr`:`qualified(type($addr))`,` + let assemblyFormat = [{ + (`align` `(` $alignment^ `)`)? + `(`$bitfield_info`,` $addr`:`qualified(type($addr))`,` $src`:`type($src) `)` attr-dict `->` type($result) }]; let builders = [ @@ -1764,14 +1768,15 @@ def CIR_SetBitfieldOp : CIR_Op<"set_bitfield"> { "unsigned":$size, "unsigned":$offset, "bool":$is_signed, - "bool":$is_volatile + "bool":$is_volatile, + CArg<"unsigned", "0">:$alignment ), [{ BitfieldInfoAttr info = BitfieldInfoAttr::get($_builder.getContext(), name, storage_type, size, offset, is_signed); - build($_builder, $_state, type, addr, src, info, is_volatile); + build($_builder, $_state, type, addr, src, info, alignment, is_volatile); }]> ]; } @@ -1823,20 +1828,23 @@ def CIR_GetBitfieldOp : CIR_Op<"get_bitfield"> { %2 = cir.load %0 : !cir.ptr<!cir.ptr<!record_type>>, !cir.ptr<!record_type> %3 = cir.get_member %2[1] {name = "e"} : !cir.ptr<!record_type> -> !cir.ptr<!u16i> - %4 = cir.get_bitfield(#bfi_e, %3 : !cir.ptr<!u16i>) -> !s32i + %4 = cir.get_bitfield align(4) (#bfi_e, %3 : !cir.ptr<!u16i>) -> !s32i ``` }]; let arguments = (ins Arg<CIR_PointerType, "the address to load from", [MemRead]>:$addr, - BitfieldInfoAttr:$bitfield_info, + CIR_BitfieldInfoAttr:$bitfield_info, + DefaultValuedOptionalAttr<I64Attr, "0">:$alignment, UnitAttr:$is_volatile ); let results = (outs CIR_IntType:$result); - let assemblyFormat = [{ `(`$bitfield_info `,` $addr attr-dict `:` - qualified(type($addr)) `)` `->` type($result) }]; + let assemblyFormat = [{ + (`align` `(` $alignment^ `)`)? + `(`$bitfield_info `,` $addr attr-dict `:` + qualified(type($addr)) `)` `->` type($result) }]; let builders = [ OpBuilder<(ins "mlir::Type":$type, @@ -1846,14 +1854,15 @@ def CIR_GetBitfieldOp : CIR_Op<"get_bitfield"> { "unsigned":$size, "unsigned":$offset, "bool":$is_signed, - "bool":$is_volatile + "bool":$is_volatile, + CArg<"unsigned", "0">:$alignment ), [{ BitfieldInfoAttr info = BitfieldInfoAttr::get($_builder.getContext(), name, storage_type, size, offset, is_signed); - build($_builder, $_state, type, addr, info, is_volatile); + build($_builder, $_state, type, addr, info, alignment, is_volatile); }]> ]; } @@ -1937,6 +1946,10 @@ def CIR_FuncOp : CIR_Op<"func", [ The function linkage information is specified by `linkage`, as defined by `GlobalLinkageKind` attribute. + The `no_proto` keyword is used to identify functions that were declared + without a prototype and, consequently, may contain calls with invalid + arguments and undefined behavior. + Example: ```mlir @@ -1955,6 +1968,7 @@ def CIR_FuncOp : CIR_Op<"func", [ let arguments = (ins SymbolNameAttr:$sym_name, CIR_VisibilityAttr:$global_visibility, TypeAttrOf<CIR_FuncType>:$function_type, + UnitAttr:$no_proto, UnitAttr:$dso_local, DefaultValuedAttr<CIR_GlobalLinkageKind, "cir::GlobalLinkageKind::ExternalLinkage">:$linkage, @@ -1996,13 +2010,6 @@ def CIR_FuncOp : CIR_Op<"func", [ return getFunctionType().getReturnTypes(); } - // TODO(cir): this should be an operand attribute, but for now we just hard- - // wire this as a function. Will later add a $no_proto argument to this op. - bool getNoProto() { - assert(!cir::MissingFeatures::opFuncNoProto()); - return false; - } - //===------------------------------------------------------------------===// // SymbolOpInterface Methods //===------------------------------------------------------------------===// @@ -2220,6 +2227,71 @@ def CIR_TrapOp : CIR_Op<"trap", [Terminator]> { } //===----------------------------------------------------------------------===// +// ArrayCtor & ArrayDtor +//===----------------------------------------------------------------------===// + +class CIR_ArrayInitDestroy<string mnemonic> : CIR_Op<mnemonic> { + let arguments = (ins + Arg<CIR_PtrToArray, "array address", [MemWrite, MemRead]>:$addr + ); + + let regions = (region SizedRegion<1>:$body); + let assemblyFormat = [{ + $addr `:` qualified(type($addr)) $body attr-dict + }]; + + let builders = [ + OpBuilder<(ins "mlir::Value":$addr, + "llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>":$regionBuilder), [{ + assert(regionBuilder && "builder callback expected"); + mlir::OpBuilder::InsertionGuard guard($_builder); + mlir::Region *r = $_state.addRegion(); + $_state.addOperands(ValueRange{addr}); + $_builder.createBlock(r); + regionBuilder($_builder, $_state.location); + }]> + ]; +} + +def CIR_ArrayCtor : CIR_ArrayInitDestroy<"array.ctor"> { + let summary = "Initialize array elements with C++ constructors"; + let description = [{ + Initialize each array element using the same C++ constructor. This + operation has one region, with one single block. The block has an + incoming argument for the current array element to initialize. + + Example: + + ```mlir + cir.array.ctor(%0 : !cir.ptr<!cir.array<!rec_S x 42>>) { + ^bb0(%arg0: !cir.ptr<!rec_S>): + cir.call @some_ctor(%arg0) : (!cir.ptr<!rec_S>) -> () + cir.yield + } + ``` + }]; +} + +def CIR_ArrayDtor : CIR_ArrayInitDestroy<"array.dtor"> { + let summary = "Destroy array elements with C++ dtors"; + let description = [{ + Destroy each array element using the same C++ destructor. This + operation has one region, with one single block. The block has an + incoming argument for the current array element to destruct. + + Example: + + ```mlir + cir.array.dtor(%0 : !cir.ptr<!cir.array<!rec_S x 42>>) { + ^bb0(%arg0: !cir.ptr<!rec_S>): + cir.call @some_dtor(%arg0) : (!cir.ptr<!rec_S>) -> () + cir.yield + } + ``` + }]; +} + +//===----------------------------------------------------------------------===// // VecCreate //===----------------------------------------------------------------------===// @@ -2751,6 +2823,53 @@ def CIR_ComplexSubOp : CIR_Op<"complex.sub", [ }]; } +//===----------------------------------------------------------------------===// +// ComplexMulOp +//===----------------------------------------------------------------------===// + +def CIR_ComplexRangeKind : CIR_I32EnumAttr< + "ComplexRangeKind", "complex multiplication and division implementation", [ + I32EnumAttrCase<"Full", 0, "full">, + I32EnumAttrCase<"Improved", 1, "improved">, + I32EnumAttrCase<"Promoted", 2, "promoted">, + I32EnumAttrCase<"Basic", 3, "basic">, +]>; + +def CIR_ComplexMulOp : CIR_Op<"complex.mul", [ + Pure, SameOperandsAndResultType +]> { + let summary = "Complex multiplication"; + let description = [{ + The `cir.complex.mul` operation takes two complex numbers and returns + their product. + + Range is used to select the implementation used when the operation + is lowered to the LLVM dialect. For multiplication, 'improved', + 'promoted', and 'basic' are all handled equivalently, producing the + algebraic formula with no special handling for NaN value. If 'full' is + used, a runtime-library function is called if one of the intermediate + calculations produced a NaN value. + + Example: + + ```mlir + %2 = cir.complex.mul %0, %1 range(basic) : !cir.complex<!cir.float> + %2 = cir.complex.mul %0, %1 range(full) : !cir.complex<!cir.float> + ``` + }]; + + let arguments = (ins + CIR_ComplexType:$lhs, + CIR_ComplexType:$rhs, + CIR_ComplexRangeKind:$range + ); + + let results = (outs CIR_ComplexType:$result); + + let assemblyFormat = [{ + $lhs `,` $rhs `range` `(` $range `)` `:` qualified(type($result)) attr-dict + }]; +} //===----------------------------------------------------------------------===// // Bit Manipulation Operations @@ -2764,6 +2883,8 @@ class CIR_BitOpBase<string mnemonic, TypeConstraint operandTy> let assemblyFormat = [{ $input `:` type($result) attr-dict }]; + + let hasFolder = 1; } class CIR_BitZeroCountOpBase<string mnemonic, TypeConstraint operandTy> @@ -2856,6 +2977,28 @@ def CIR_BitCtzOp : CIR_BitZeroCountOpBase<"ctz", }]; } +def CIR_BitFfsOp : CIR_BitOpBase<"ffs", CIR_SIntOfWidths<[32, 64]>> { + let summary = "Get the position of the least significant 1-bit in input"; + let description = [{ + Compute the 1-based position of the least significant 1-bit of the input. + + The input integer must be a signed integer. The `cir.ffs` operation returns + one plus the index of the least significant 1-bit of the input signed + integer. If the input integer is 0, `cir.ffs` yields 0. + + Example: + + ```mlir + !s32i = !cir.int<s, 32> + + // %0 = 0x0010_1000 + %0 = cir.const #cir.int<40> : !s32i + // #1 will be 4 since the 4th least significant bit is 1. + %1 = cir.ffs %0 : !s32i + ``` + }]; +} + def CIR_BitParityOp : CIR_BitOpBase<"parity", CIR_UIntOfWidths<[32, 64]>> { let summary = "Get the parity of input"; let description = [{ @@ -2971,6 +3114,8 @@ def CIR_RotateOp : CIR_Op<"rotate", [Pure, SameOperandsAndResultType]> { bool isRotateLeft() { return getRotateLeft(); } bool isRotateRight() { return !getRotateLeft(); } }]; + + let hasFolder = 1; } //===----------------------------------------------------------------------===// @@ -2995,6 +3140,27 @@ def CIR_AssumeOp : CIR_Op<"assume"> { }]; } +def CIR_AssumeSepStorageOp : CIR_Op<"assume_separate_storage", [ + SameTypeOperands +]> { + let summary = + "Tell the optimizer that two pointers point to different allocations"; + let description = [{ + The `cir.assume_separate_storage` operation takes two pointers as arguments, + and the operation tells the optimizer that these two pointers point to + different allocations. + + This operation corresponds to the `__builtin_assume_separate_storage` + builtin function. + }]; + + let arguments = (ins CIR_VoidPtrType:$ptr1, CIR_VoidPtrType:$ptr2); + + let assemblyFormat = [{ + $ptr1 `,` $ptr2 `:` qualified(type($ptr1)) attr-dict + }]; +} + //===----------------------------------------------------------------------===// // Branch Probability Operations //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index 2bf7758..d7d55df 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -166,6 +166,12 @@ def CIR_AnyIntOrFloatType : AnyTypeOf<[CIR_AnyFloatType, CIR_AnyIntType], def CIR_AnyComplexType : CIR_TypeBase<"::cir::ComplexType", "complex type">; //===----------------------------------------------------------------------===// +// Array Type predicates +//===----------------------------------------------------------------------===// + +def CIR_AnyArrayType : CIR_TypeBase<"::cir::ArrayType", "array type">; + +//===----------------------------------------------------------------------===// // Pointer Type predicates //===----------------------------------------------------------------------===// @@ -216,6 +222,8 @@ def CIR_PtrToIntOrFloatType : CIR_PtrToType<CIR_AnyIntOrFloatType>; def CIR_PtrToComplexType : CIR_PtrToType<CIR_AnyComplexType>; +def CIR_PtrToArray : CIR_PtrToType<CIR_AnyArrayType>; + //===----------------------------------------------------------------------===// // Vector Type predicates //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/Dialect/Passes.h b/clang/include/clang/CIR/Dialect/Passes.h index 02210ec..7a202b1 100644 --- a/clang/include/clang/CIR/Dialect/Passes.h +++ b/clang/include/clang/CIR/Dialect/Passes.h @@ -25,6 +25,7 @@ std::unique_ptr<Pass> createCIRFlattenCFGPass(); std::unique_ptr<Pass> createCIRSimplifyPass(); std::unique_ptr<Pass> createHoistAllocasPass(); std::unique_ptr<Pass> createLoweringPreparePass(); +std::unique_ptr<Pass> createLoweringPreparePass(clang::ASTContext *astCtx); void populateCIRPreLoweringPasses(mlir::OpPassManager &pm); diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 182e4b6..adc7b5f 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -73,14 +73,16 @@ struct MissingFeatures { // FuncOp handling static bool opFuncOpenCLKernelMetadata() { return false; } static bool opFuncAstDeclAttr() { return false; } + static bool opFuncAttributesForDefinition() { return false; } static bool opFuncCallingConv() { return false; } - static bool opFuncExtraAttrs() { return false; } - static bool opFuncNoProto() { return false; } static bool opFuncCPUAndFeaturesAttributes() { return false; } - static bool opFuncSection() { return false; } - static bool opFuncMultipleReturnVals() { return false; } - static bool opFuncAttributesForDefinition() { return false; } + static bool opFuncExceptions() { return false; } + static bool opFuncExtraAttrs() { return false; } static bool opFuncMaybeHandleStaticInExternC() { return false; } + static bool opFuncMultipleReturnVals() { return false; } + static bool opFuncOperandBundles() { return false; } + static bool opFuncParameterAttributes() { return false; } + static bool opFuncSection() { return false; } static bool setLLVMFunctionFEnvAttributes() { return false; } static bool setFunctionAttributes() { return false; } @@ -96,7 +98,6 @@ struct MissingFeatures { static bool opCallReturn() { return false; } static bool opCallArgEvaluationOrder() { return false; } static bool opCallCallConv() { return false; } - static bool opCallNoPrototypeFunc() { return false; } static bool opCallMustTail() { return false; } static bool opCallVirtual() { return false; } static bool opCallInAlloca() { return false; } @@ -109,6 +110,7 @@ struct MissingFeatures { static bool opCallCIRGenFuncInfoExtParamInfo() { return false; } static bool opCallLandingPad() { return false; } static bool opCallContinueBlock() { return false; } + static bool opCallChain() { return false; } // CXXNewExpr static bool exprNewNullCheck() { return false; } @@ -196,6 +198,8 @@ struct MissingFeatures { static bool cxxRecordStaticMembers() { return false; } static bool dataLayoutTypeAllocSize() { return false; } static bool deferredCXXGlobalInit() { return false; } + static bool ehCleanupFlags() { return false; } + static bool ehstackBranches() { return false; } static bool emitCheckedInBoundsGEP() { return false; } static bool emitCondLikelihoodViaExpectIntrinsic() { return false; } static bool emitLifetimeMarkers() { return false; } @@ -213,6 +217,7 @@ struct MissingFeatures { static bool intrinsics() { return false; } static bool isMemcpyEquivalentSpecialMember() { return false; } static bool isTrivialCtorOrDtor() { return false; } + static bool lambdaCaptures() { return false; } static bool lambdaFieldToName() { return false; } static bool loopInfoStack() { return false; } static bool lowerAggregateLoadStore() { return false; } @@ -222,7 +227,6 @@ struct MissingFeatures { static bool moduleNameHash() { return false; } static bool msabi() { return false; } static bool needsGlobalCtorDtor() { return false; } - static bool nonFineGrainedBitfields() { return false; } static bool objCBlocks() { return false; } static bool objCGC() { return false; } static bool objCLifetime() { return false; } @@ -252,9 +256,9 @@ struct MissingFeatures { static bool writebacks() { return false; } static bool appleKext() { return false; } static bool dtorCleanups() { return false; } - static bool completeDtors() { return false; } static bool vtableInitialization() { return false; } static bool msvcBuiltins() { return false; } + static bool vlas() { return false; } // Missing types static bool dataMemberType() { return false; } diff --git a/clang/include/clang/Driver/CudaInstallationDetector.h b/clang/include/clang/Driver/CudaInstallationDetector.h new file mode 100644 index 0000000..0fecbfe --- /dev/null +++ b/clang/include/clang/Driver/CudaInstallationDetector.h @@ -0,0 +1,76 @@ +//===-- CudaInstallationDetector.h - Cuda Instalation Detector --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DRIVER_CUDAINSTALLATIONDETECTOR_H +#define LLVM_CLANG_DRIVER_CUDAINSTALLATIONDETECTOR_H + +#include "clang/Basic/Cuda.h" +#include "clang/Driver/Driver.h" +#include <bitset> + +namespace clang { +namespace driver { + +/// A class to find a viable CUDA installation +class CudaInstallationDetector { +private: + const Driver &D; + bool IsValid = false; + CudaVersion Version = CudaVersion::UNKNOWN; + std::string InstallPath; + std::string BinPath; + std::string LibDevicePath; + std::string IncludePath; + llvm::StringMap<std::string> LibDeviceMap; + + // CUDA architectures for which we have raised an error in + // CheckCudaVersionSupportsArch. + mutable std::bitset<(int)OffloadArch::LAST> ArchsWithBadVersion; + +public: + CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, + const llvm::opt::ArgList &Args); + + void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; + + /// Emit an error if Version does not support the given Arch. + /// + /// If either Version or Arch is unknown, does not emit an error. Emits at + /// most one error per Arch. + void CheckCudaVersionSupportsArch(OffloadArch Arch) const; + + /// Check whether we detected a valid Cuda install. + bool isValid() const { return IsValid; } + /// Print information about the detected CUDA installation. + void print(raw_ostream &OS) const; + + /// Get the detected Cuda install's version. + CudaVersion version() const { + return Version == CudaVersion::NEW ? CudaVersion::PARTIALLY_SUPPORTED + : Version; + } + /// Get the detected Cuda installation path. + StringRef getInstallPath() const { return InstallPath; } + /// Get the detected path to Cuda's bin directory. + StringRef getBinPath() const { return BinPath; } + /// Get the detected Cuda Include path. + StringRef getIncludePath() const { return IncludePath; } + /// Get the detected Cuda device library path. + StringRef getLibDevicePath() const { return LibDevicePath; } + /// Get libdevice file for given architecture + std::string getLibDeviceFile(StringRef Gpu) const { + return LibDeviceMap.lookup(Gpu); + } + void WarnIfUnsupportedVersion() const; +}; + +} // namespace driver +} // namespace clang + +#endif // LLVM_CLANG_DRIVER_CUDAINSTALLATIONDETECTOR_H diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index d9e328f..4d32552 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -337,6 +337,10 @@ private: /// "clang" as it's first argument. const char *PrependArg; + /// The default value of -fuse-ld= option. An empty string means the default + /// system linker. + std::string PreferredLinker; + /// Whether to check that input files exist when constructing compilation /// jobs. LLVM_PREFERRED_TYPE(bool) @@ -355,6 +359,9 @@ public: phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg = nullptr) const; + llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> + executeProgram(llvm::ArrayRef<llvm::StringRef> Args) const; + private: /// Certain options suppress the 'no input files' warning. LLVM_PREFERRED_TYPE(bool) @@ -367,10 +374,6 @@ private: /// stored in it, and will clean them up when torn down. mutable llvm::StringMap<std::unique_ptr<ToolChain>> ToolChains; - /// The associated offloading architectures with each toolchain. - llvm::DenseMap<const ToolChain *, llvm::SmallVector<llvm::StringRef>> - OffloadArchs; - private: /// TranslateInputArgs - Create a new derived argument list from the input /// arguments, after applying the standard argument translations. @@ -450,6 +453,11 @@ public: return ClangExecutable.c_str(); } + StringRef getPreferredLinker() const { return PreferredLinker; } + void setPreferredLinker(std::string Value) { + PreferredLinker = std::move(Value); + } + bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; } bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; } @@ -537,8 +545,7 @@ public: /// empty string. llvm::SmallVector<StringRef> getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, - Action::OffloadKind Kind, const ToolChain *TC, - bool SpecificToolchain = true) const; + Action::OffloadKind Kind, const ToolChain &TC) const; /// Check that the file referenced by Value exists. If it doesn't, /// issue a diagnostic and return false. diff --git a/clang/include/clang/Driver/LazyDetector.h b/clang/include/clang/Driver/LazyDetector.h new file mode 100644 index 0000000..5bd1d01 --- /dev/null +++ b/clang/include/clang/Driver/LazyDetector.h @@ -0,0 +1,45 @@ +//===--- LazyDetector.h - Lazy ToolChain Detection --------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DRIVER_LAZYDETECTOR_H +#define LLVM_CLANG_DRIVER_LAZYDETECTOR_H + +#include "clang/Driver/Tool.h" +#include "clang/Driver/ToolChain.h" +#include <optional> + +namespace clang { + +/// Simple wrapper for toolchain detector with costly initialization. This +/// delays the creation of the actual detector until its first usage. + +template <class T> class LazyDetector { + const driver::Driver &D; + llvm::Triple Triple; + const llvm::opt::ArgList &Args; + + std::optional<T> Detector; + +public: + LazyDetector(const driver::Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args) + : D(D), Triple(Triple), Args(Args) {} + T *operator->() { + if (!Detector) + Detector.emplace(D, Triple, Args); + return &*Detector; + } + const T *operator->() const { + return const_cast<T const *>( + const_cast<LazyDetector &>(*this).operator->()); + } +}; + +} // end namespace clang + +#endif // LLVM_CLANG_DRIVER_LAZYDETECTOR_H diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 6c22f06..3c04aeb 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1156,7 +1156,7 @@ def offload_arch_EQ : CommaJoined<["--"], "offload-arch=">, "If 'native' is used the compiler will detect locally installed architectures. " "For HIP offloading, the device architecture can be followed by target ID features " "delimited by a colon (e.g. gfx908:xnack+:sramecc-). May be specified more than once.">; -def no_offload_arch_EQ : Joined<["--"], "no-offload-arch=">, +def no_offload_arch_EQ : CommaJoined<["--"], "no-offload-arch=">, Visibility<[ClangOption, FlangOption]>, HelpText<"Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. " "'all' resets the list to its default value.">; @@ -1624,7 +1624,7 @@ defm auto_import : BoolFOption<"auto-import", // 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]>, +def offload_EQ : CommaJoined<["--"], "offload=">, Flags<[NoXarchOption]>, Alias<offload_targets_EQ>, HelpText<"Specify comma-separated list of offloading target triples (CUDA and HIP only)">; // C++ Coroutines @@ -1904,6 +1904,14 @@ defm bounds_safety : BoolFOption< BothFlags<[], [CC1Option], " experimental bounds safety extension for C">>; +defm lifetime_safety : BoolFOption< + "experimental-lifetime-safety", + LangOpts<"EnableLifetimeSafety">, DefaultFalse, + PosFlag<SetTrue, [], [CC1Option], "Enable">, + NegFlag<SetFalse, [], [CC1Option], "Disable">, + BothFlags<[], [CC1Option], + " experimental lifetime safety for C++">>; + defm addrsig : BoolFOption<"addrsig", CodeGenOpts<"Addrsig">, DefaultFalse, PosFlag<SetTrue, [], [ClangOption, CC1Option], "Emit">, @@ -2312,21 +2320,21 @@ def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group<f_Group>, defm atomic_remote_memory : BoolFOption<"atomic-remote-memory", LangOpts<"AtomicRemoteMemory">, DefaultFalse, - PosFlag<SetTrue, [], [ClangOption, CC1Option], "May have">, - NegFlag<SetFalse, [], [ClangOption], "Assume no">, - BothFlags<[], [ClangOption], " atomic operations on remote memory">>; + PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "May have">, + NegFlag<SetFalse, [], [ClangOption, FlangOption], "Assume no">, + BothFlags<[], [ClangOption, FlangOption], " atomic operations on remote memory">>; defm atomic_fine_grained_memory : BoolFOption<"atomic-fine-grained-memory", LangOpts<"AtomicFineGrainedMemory">, DefaultFalse, - PosFlag<SetTrue, [], [ClangOption, CC1Option], "May have">, - NegFlag<SetFalse, [], [ClangOption], "Assume no">, - BothFlags<[], [ClangOption], " atomic operations on fine-grained memory">>; + PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "May have">, + NegFlag<SetFalse, [], [ClangOption, FlangOption], "Assume no">, + BothFlags<[], [ClangOption, FlangOption], " atomic operations on fine-grained memory">>; defm atomic_ignore_denormal_mode : BoolFOption<"atomic-ignore-denormal-mode", LangOpts<"AtomicIgnoreDenormalMode">, DefaultFalse, - PosFlag<SetTrue, [], [ClangOption, CC1Option], "Allow">, - NegFlag<SetFalse, [], [ClangOption], "Disallow">, - BothFlags<[], [ClangOption], " atomic operations to ignore denormal mode">>; + PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "Allow">, + NegFlag<SetFalse, [], [ClangOption, FlangOption], "Disallow">, + BothFlags<[], [ClangOption, FlangOption], " atomic operations to ignore denormal mode">>; defm memory_profile : OptInCC1FFlag<"memory-profile", "Enable", "Disable", " heap memory profiling">; def fmemory_profile_EQ : Joined<["-"], "fmemory-profile=">, @@ -2589,6 +2597,16 @@ def fsanitize_undefined_trap_on_error def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-trap-on-error">, Group<f_clang_Group>, Alias<fno_sanitize_trap_EQ>, AliasArgs<["undefined"]>; +defm sanitize_debug_trap_reasons + : BoolFOption< + "sanitize-debug-trap-reasons", + CodeGenOpts<"SanitizeDebugTrapReasons">, DefaultTrue, + PosFlag<SetTrue, [], [ClangOption, CC1Option], + "Annotate trap blocks in debug info with UBSan trap reasons">, + NegFlag<SetFalse, [], [ClangOption, CC1Option], + "Do not annotate trap blocks in debug info with UBSan trap " + "reasons">>; + defm sanitize_minimal_runtime : BoolOption<"f", "sanitize-minimal-runtime", CodeGenOpts<"SanitizeMinimalRuntime">, DefaultFalse, PosFlag<SetTrue>, @@ -3257,13 +3275,14 @@ defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf", "Perform ODR checks for decls in the global module fragment.">>, Group<f_Group>; -def modules_reduced_bmi : Flag<["-"], "fmodules-reduced-bmi">, - Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Generate the reduced BMI">, - MarshallingInfoFlag<FrontendOpts<"GenReducedBMI">>; +defm modules_reduced_bmi : BoolOption<"f", "modules-reduced-bmi", + FrontendOpts<"GenReducedBMI">, DefaultFalse, + NegFlag<SetFalse>, + PosFlag<SetTrue, [], [ClangOption, CC1Option], + "Generate the reduced BMI">>; def experimental_modules_reduced_bmi : Flag<["-"], "fexperimental-modules-reduced-bmi">, - Group<f_Group>, Visibility<[ClangOption, CC1Option]>, Alias<modules_reduced_bmi>; + Group<f_Group>, Visibility<[ClangOption, CC1Option]>, Alias<fmodules_reduced_bmi>; def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">, Visibility<[ClangOption, CC1Option, CLOption]>, @@ -5293,6 +5312,8 @@ def mextended_const : Flag<["-"], "mextended-const">, Group<m_wasm_Features_Grou def mno_extended_const : Flag<["-"], "mno-extended-const">, Group<m_wasm_Features_Group>; def mfp16 : Flag<["-"], "mfp16">, Group<m_wasm_Features_Group>; def mno_fp16 : Flag<["-"], "mno-fp16">, Group<m_wasm_Features_Group>; +def mgc : Flag<["-"], "mgc">, Group<m_wasm_Features_Group>; +def mno_gc : Flag<["-"], "mno-gc">, Group<m_wasm_Features_Group>; def mmultimemory : Flag<["-"], "mmultimemory">, Group<m_wasm_Features_Group>; def mno_multimemory : Flag<["-"], "mno-multimemory">, Group<m_wasm_Features_Group>; def mmultivalue : Flag<["-"], "mmultivalue">, Group<m_wasm_Features_Group>; @@ -5351,9 +5372,9 @@ defm amdgpu_precise_memory_op " precise memory mode (AMDGPU only)">; def munsafe_fp_atomics : Flag<["-"], "munsafe-fp-atomics">, - Visibility<[ClangOption, CC1Option]>, Alias<fatomic_ignore_denormal_mode>; + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, Alias<fatomic_ignore_denormal_mode>; def mno_unsafe_fp_atomics : Flag<["-"], "mno-unsafe-fp-atomics">, - Visibility<[ClangOption]>, Alias<fno_atomic_ignore_denormal_mode>; + Visibility<[ClangOption, FlangOption]>, Alias<fno_atomic_ignore_denormal_mode>; def faltivec : Flag<["-"], "faltivec">, Group<f_Group>; def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>; @@ -7129,6 +7150,8 @@ def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group HelpText<"Specify where to find the compiled intrinsic modules">, DocBrief<[{This option specifies the location of pre-compiled intrinsic modules, if they are not in the default location expected by the compiler.}]>; +def fintrinsic_modules_path_EQ : Joined<["-"], "fintrinsic-modules-path=">, + Group<f_Group>, Alias<fintrinsic_modules_path>; defm backslash : OptInFC1FFlag<"backslash", "Specify that backslash in string introduces an escape character">; defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of .NEQV.">; @@ -8250,6 +8273,9 @@ def stats_file : Joined<["-"], "stats-file=">, def stats_file_append : Flag<["-"], "stats-file-append">, HelpText<"If stats should be appended to stats-file instead of overwriting it">, MarshallingInfoFlag<FrontendOpts<"AppendStats">>; +def stats_file_timers : Flag<["-"], "stats-file-timers">, + HelpText<"If stats should include timers.">, + MarshallingInfoFlag<CodeGenOpts<"TimePassesStatsFile">>; def fdump_record_layouts_simple : Flag<["-"], "fdump-record-layouts-simple">, HelpText<"Dump record layout information in a simple form used for testing">, MarshallingInfoFlag<LangOpts<"DumpRecordLayoutsSimple">>; diff --git a/clang/include/clang/Driver/RocmInstallationDetector.h b/clang/include/clang/Driver/RocmInstallationDetector.h new file mode 100644 index 0000000..3a325a6 --- /dev/null +++ b/clang/include/clang/Driver/RocmInstallationDetector.h @@ -0,0 +1,303 @@ +//===-- RocmInstallationDetector.h - ROCm Instalation Detector --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DRIVER_ROCMINSTALLATIONDETECTOR_H +#define LLVM_CLANG_DRIVER_ROCMINSTALLATIONDETECTOR_H + +#include "clang/Driver/Driver.h" + +namespace clang { +namespace driver { + +/// ABI version of device library. +struct DeviceLibABIVersion { + unsigned ABIVersion = 0; + DeviceLibABIVersion(unsigned V) : ABIVersion(V) {} + static DeviceLibABIVersion fromCodeObjectVersion(unsigned CodeObjectVersion) { + if (CodeObjectVersion < 4) + CodeObjectVersion = 4; + return DeviceLibABIVersion(CodeObjectVersion * 100); + } + /// Whether ABI version bc file is requested. + /// ABIVersion is code object version multiplied by 100. Code object v4 + /// and below works with ROCm 5.0 and below which does not have + /// abi_version_*.bc. Code object v5 requires abi_version_500.bc. + bool requiresLibrary() { return ABIVersion >= 500; } + std::string toString() { return Twine(getAsCodeObjectVersion()).str(); } + + unsigned getAsCodeObjectVersion() const { + assert(ABIVersion % 100 == 0 && "Not supported"); + return ABIVersion / 100; + } +}; + +/// A class to find a viable ROCM installation +/// TODO: Generalize to handle libclc. +class RocmInstallationDetector { +private: + struct ConditionalLibrary { + SmallString<0> On; + SmallString<0> Off; + + bool isValid() const { return !On.empty() && !Off.empty(); } + + StringRef get(bool Enabled) const { + assert(isValid()); + return Enabled ? On : Off; + } + }; + + // Installation path candidate. + struct Candidate { + llvm::SmallString<0> Path; + bool StrictChecking; + // Release string for ROCm packages built with SPACK if not empty. The + // installation directories of ROCm packages built with SPACK follow the + // convention <package_name>-<rocm_release_string>-<hash>. + std::string SPACKReleaseStr; + + bool isSPACK() const { return !SPACKReleaseStr.empty(); } + Candidate(std::string Path, bool StrictChecking = false, + StringRef SPACKReleaseStr = {}) + : Path(Path), StrictChecking(StrictChecking), + SPACKReleaseStr(SPACKReleaseStr.str()) {} + }; + + struct CommonBitcodeLibsPreferences { + CommonBitcodeLibsPreferences(const Driver &D, + const llvm::opt::ArgList &DriverArgs, + StringRef GPUArch, + const Action::OffloadKind DeviceOffloadingKind, + const bool NeedsASanRT); + + DeviceLibABIVersion ABIVer; + bool IsOpenMP; + bool Wave64; + bool DAZ; + bool FiniteOnly; + bool UnsafeMathOpt; + bool FastRelaxedMath; + bool CorrectSqrt; + bool GPUSan; + }; + + const Driver &D; + bool HasHIPRuntime = false; + bool HasDeviceLibrary = false; + bool HasHIPStdParLibrary = false; + bool HasRocThrustLibrary = false; + bool HasRocPrimLibrary = false; + + // Default version if not detected or specified. + const unsigned DefaultVersionMajor = 3; + const unsigned DefaultVersionMinor = 5; + const char *DefaultVersionPatch = "0"; + + // The version string in Major.Minor.Patch format. + std::string DetectedVersion; + // Version containing major and minor. + llvm::VersionTuple VersionMajorMinor; + // Version containing patch. + std::string VersionPatch; + + // ROCm path specified by --rocm-path. + StringRef RocmPathArg; + // ROCm device library paths specified by --rocm-device-lib-path. + std::vector<std::string> RocmDeviceLibPathArg; + // HIP runtime path specified by --hip-path. + StringRef HIPPathArg; + // HIP Standard Parallel Algorithm acceleration library specified by + // --hipstdpar-path + StringRef HIPStdParPathArg; + // rocThrust algorithm library specified by --hipstdpar-thrust-path + StringRef HIPRocThrustPathArg; + // rocPrim algorithm library specified by --hipstdpar-prim-path + StringRef HIPRocPrimPathArg; + // HIP version specified by --hip-version. + StringRef HIPVersionArg; + // Wheter -nogpulib is specified. + bool NoBuiltinLibs = false; + + // Paths + SmallString<0> InstallPath; + SmallString<0> BinPath; + SmallString<0> LibPath; + SmallString<0> LibDevicePath; + SmallString<0> IncludePath; + SmallString<0> SharePath; + llvm::StringMap<std::string> LibDeviceMap; + + // Libraries that are always linked. + SmallString<0> OCML; + SmallString<0> OCKL; + + // Libraries that are always linked depending on the language + SmallString<0> OpenCL; + + // Asan runtime library + SmallString<0> AsanRTL; + + // Libraries swapped based on compile flags. + ConditionalLibrary WavefrontSize64; + ConditionalLibrary FiniteOnly; + ConditionalLibrary UnsafeMath; + ConditionalLibrary DenormalsAreZero; + ConditionalLibrary CorrectlyRoundedSqrt; + + // Maps ABI version to library path. The version number is in the format of + // three digits as used in the ABI version library name. + std::map<unsigned, std::string> ABIVersionMap; + + // Cache ROCm installation search paths. + SmallVector<Candidate, 4> ROCmSearchDirs; + bool PrintROCmSearchDirs; + bool Verbose; + + bool allGenericLibsValid() const { + return !OCML.empty() && !OCKL.empty() && !OpenCL.empty() && + WavefrontSize64.isValid() && FiniteOnly.isValid() && + UnsafeMath.isValid() && DenormalsAreZero.isValid() && + CorrectlyRoundedSqrt.isValid(); + } + + void scanLibDevicePath(llvm::StringRef Path); + bool parseHIPVersionFile(llvm::StringRef V); + const SmallVectorImpl<Candidate> &getInstallationPathCandidates(); + + /// Find the path to a SPACK package under the ROCm candidate installation + /// directory if the candidate is a SPACK ROCm candidate. \returns empty + /// string if the candidate is not SPACK ROCm candidate or the requested + /// package is not found. + llvm::SmallString<0> findSPACKPackage(const Candidate &Cand, + StringRef PackageName); + +public: + RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, + const llvm::opt::ArgList &Args, + bool DetectHIPRuntime = true, + bool DetectDeviceLib = false); + + /// Get file paths of default bitcode libraries common to AMDGPU based + /// toolchains. + llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> + getCommonBitcodeLibs(const llvm::opt::ArgList &DriverArgs, + StringRef LibDeviceFile, StringRef GPUArch, + const Action::OffloadKind DeviceOffloadingKind, + const bool NeedsASanRT) const; + /// Check file paths of default bitcode libraries common to AMDGPU based + /// toolchains. \returns false if there are invalid or missing files. + bool checkCommonBitcodeLibs(StringRef GPUArch, StringRef LibDeviceFile, + DeviceLibABIVersion ABIVer) const; + + /// Check whether we detected a valid HIP runtime. + bool hasHIPRuntime() const { return HasHIPRuntime; } + + /// Check whether we detected a valid ROCm device library. + bool hasDeviceLibrary() const { return HasDeviceLibrary; } + + /// Check whether we detected a valid HIP STDPAR Acceleration library. + bool hasHIPStdParLibrary() const { return HasHIPStdParLibrary; } + + /// Print information about the detected ROCm installation. + void print(raw_ostream &OS) const; + + /// Get the detected Rocm install's version. + // RocmVersion version() const { return Version; } + + /// Get the detected Rocm installation path. + StringRef getInstallPath() const { return InstallPath; } + + /// Get the detected path to Rocm's bin directory. + // StringRef getBinPath() const { return BinPath; } + + /// Get the detected Rocm Include path. + StringRef getIncludePath() const { return IncludePath; } + + /// Get the detected Rocm library path. + StringRef getLibPath() const { return LibPath; } + + /// Get the detected Rocm device library path. + StringRef getLibDevicePath() const { return LibDevicePath; } + + StringRef getOCMLPath() const { + assert(!OCML.empty()); + return OCML; + } + + StringRef getOCKLPath() const { + assert(!OCKL.empty()); + return OCKL; + } + + StringRef getOpenCLPath() const { + assert(!OpenCL.empty()); + return OpenCL; + } + + /// Returns empty string of Asan runtime library is not available. + StringRef getAsanRTLPath() const { return AsanRTL; } + + StringRef getWavefrontSize64Path(bool Enabled) const { + return WavefrontSize64.get(Enabled); + } + + StringRef getFiniteOnlyPath(bool Enabled) const { + return FiniteOnly.get(Enabled); + } + + StringRef getUnsafeMathPath(bool Enabled) const { + return UnsafeMath.get(Enabled); + } + + StringRef getDenormalsAreZeroPath(bool Enabled) const { + return DenormalsAreZero.get(Enabled); + } + + StringRef getCorrectlyRoundedSqrtPath(bool Enabled) const { + return CorrectlyRoundedSqrt.get(Enabled); + } + + StringRef getABIVersionPath(DeviceLibABIVersion ABIVer) const { + auto Loc = ABIVersionMap.find(ABIVer.ABIVersion); + if (Loc == ABIVersionMap.end()) + return StringRef(); + return Loc->second; + } + + /// Get libdevice file for given architecture + StringRef getLibDeviceFile(StringRef Gpu) const { + auto Loc = LibDeviceMap.find(Gpu); + if (Loc == LibDeviceMap.end()) + return ""; + return Loc->second; + } + + void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; + + void detectDeviceLibrary(); + void detectHIPRuntime(); + + /// Get the values for --rocm-device-lib-path arguments + ArrayRef<std::string> getRocmDeviceLibPathArg() const { + return RocmDeviceLibPathArg; + } + + /// Get the value for --rocm-path argument + StringRef getRocmPathArg() const { return RocmPathArg; } + + /// Get the value for --hip-version argument + StringRef getHIPVersionArg() const { return HIPVersionArg; } + + StringRef getHIPVersion() const { return DetectedVersion; } +}; + +} // namespace driver +} // namespace clang + +#endif // LLVM_CLANG_DRIVER_ROCMINSTALLATIONDETECTOR_H diff --git a/clang/include/clang/Driver/SyclInstallationDetector.h b/clang/include/clang/Driver/SyclInstallationDetector.h new file mode 100644 index 0000000..6925ec2 --- /dev/null +++ b/clang/include/clang/Driver/SyclInstallationDetector.h @@ -0,0 +1,29 @@ +//===-- SyclInstallationDetector.h - SYCL Instalation Detector --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DRIVER_SYCLINSTALLATIONDETECTOR_H +#define LLVM_CLANG_DRIVER_SYCLINSTALLATIONDETECTOR_H + +#include "clang/Driver/Driver.h" + +namespace clang { +namespace driver { + +class SYCLInstallationDetector { +public: + SYCLInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, + const llvm::opt::ArgList &Args); + + void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; +}; + +} // namespace driver +} // namespace clang + +#endif // LLVM_CLANG_DRIVER_SYCLINSTALLATIONDETECTOR_H diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index b8899e7..2430563 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -202,10 +202,6 @@ protected: ToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args); - /// Executes the given \p Executable and returns the stdout. - llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> - executeToolChainProgram(StringRef Executable) const; - void setTripleEnvironment(llvm::Triple::EnvironmentType Env); virtual Tool *buildAssembler() const; @@ -806,7 +802,8 @@ public: /// Get paths for device libraries. virtual llvm::SmallVector<BitCodeLibraryInfo, 12> - getDeviceLibs(const llvm::opt::ArgList &Args) const; + getDeviceLibs(const llvm::opt::ArgList &Args, + const Action::OffloadKind DeviceOffloadingKind) const; /// Add the system specific linker arguments to use /// for the given HIP runtime library type. diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 7677604..31582a4 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -831,7 +831,7 @@ struct FormatStyle { /// Never merge functions into a single line. SFS_None, /// Only merge functions defined inside a class. Same as ``inline``, - /// except it does not implies ``empty``: i.e. top level empty functions + /// except it does not imply ``empty``: i.e. top level empty functions /// are not merged either. /// \code /// class Foo { @@ -4704,6 +4704,13 @@ struct FormatStyle { /// <conditional-body> <conditional-body> /// \endcode bool AfterIfMacros; + /// If ``true``, put a space between alternative operator ``not`` and the + /// opening parenthesis. + /// \code + /// true: false: + /// return not (a || b); vs. return not(a || b); + /// \endcode + bool AfterNot; /// If ``true``, put a space between operator overloading and opening /// parentheses. /// \code @@ -4752,9 +4759,9 @@ struct FormatStyle { : AfterControlStatements(false), AfterForeachMacros(false), AfterFunctionDeclarationName(false), AfterFunctionDefinitionName(false), AfterIfMacros(false), - AfterOverloadedOperator(false), AfterPlacementOperator(true), - AfterRequiresInClause(false), AfterRequiresInExpression(false), - BeforeNonEmptyParentheses(false) {} + AfterNot(false), AfterOverloadedOperator(false), + AfterPlacementOperator(true), AfterRequiresInClause(false), + AfterRequiresInExpression(false), BeforeNonEmptyParentheses(false) {} bool operator==(const SpaceBeforeParensCustom &Other) const { return AfterControlStatements == Other.AfterControlStatements && @@ -4763,6 +4770,7 @@ struct FormatStyle { Other.AfterFunctionDeclarationName && AfterFunctionDefinitionName == Other.AfterFunctionDefinitionName && AfterIfMacros == Other.AfterIfMacros && + AfterNot == Other.AfterNot && AfterOverloadedOperator == Other.AfterOverloadedOperator && AfterPlacementOperator == Other.AfterPlacementOperator && AfterRequiresInClause == Other.AfterRequiresInClause && diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index 2408367..02dd16c 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -420,6 +420,8 @@ public: /// @{ llvm::vfs::FileSystem &getVirtualFileSystem() const; + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> + getVirtualFileSystemPtr() const; /// @} /// @name File Manager diff --git a/clang/include/clang/Frontend/FrontendAction.h b/clang/include/clang/Frontend/FrontendAction.h index 718684a..08c5fbc 100644 --- a/clang/include/clang/Frontend/FrontendAction.h +++ b/clang/include/clang/Frontend/FrontendAction.h @@ -84,6 +84,8 @@ protected: /// \return True on success; on failure ExecutionAction() and /// EndSourceFileAction() will not be called. virtual bool BeginSourceFileAction(CompilerInstance &CI) { + if (CurrentInput.isPreprocessed()) + CI.getPreprocessor().SetMacroExpansionOnlyInDirectives(); return true; } @@ -98,7 +100,11 @@ protected: /// /// This is guaranteed to only be called following a successful call to /// BeginSourceFileAction (and BeginSourceFile). - virtual void EndSourceFileAction() {} + virtual void EndSourceFileAction() { + if (CurrentInput.isPreprocessed()) + // Reset the preprocessor macro expansion to the default. + getCompilerInstance().getPreprocessor().SetEnableMacroExpansion(); + } /// Callback at the end of processing a single input, to determine /// if the output files should be erased or not. diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index 78dff116..83d2962 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -175,31 +175,42 @@ public: llvm::Expected<llvm::orc::ExecutorAddr> getSymbolAddressFromLinkerName(llvm::StringRef LinkerName) const; - const llvm::SmallVectorImpl<Expr *> &getValuePrintingInfo() const { - return ValuePrintingInfo; - } - - Expr *SynthesizeExpr(Expr *E); + std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr); + PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU, + std::unique_ptr<llvm::Module> M = {}, + IncrementalAction *Action = nullptr); private: size_t getEffectivePTUSize() const; void markUserCodeStart(); llvm::Expected<Expr *> ExtractValueFromExpr(Expr *E); - llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall(CXXRecordDecl *CXXRD); - - CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const; - std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr); - PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU, - std::unique_ptr<llvm::Module> M = {}, - IncrementalAction *Action = nullptr); // A cache for the compiled destructors used to for de-allocation of managed // clang::Values. - llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors; + mutable llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors; - llvm::SmallVector<Expr *, 4> ValuePrintingInfo; + std::array<Expr *, 4> ValuePrintingInfo = {0}; std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder; + + /// @} + /// @name Value and pretty printing support + /// @{ + + std::string ValueDataToString(const Value &V) const; + std::string ValueTypeToString(const Value &V) const; + + llvm::Expected<Expr *> convertExprToValue(Expr *E); + + // When we deallocate clang::Value we need to run the destructor of the type. + // This function forces emission of the needed dtor. + llvm::Expected<llvm::orc::ExecutorAddr> + CompileDtorCall(CXXRecordDecl *CXXRD) const; + + /// @} + /// @name Code generation + /// @{ + CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const; }; } // namespace clang diff --git a/clang/include/clang/Interpreter/Value.h b/clang/include/clang/Interpreter/Value.h index a93c084..b91301e 100644 --- a/clang/include/clang/Interpreter/Value.h +++ b/clang/include/clang/Interpreter/Value.h @@ -35,6 +35,7 @@ #include "llvm/Config/llvm-config.h" // for LLVM_BUILD_LLVM_DYLIB, LLVM_BUILD_SHARED_LIBS #include "llvm/Support/Compiler.h" +#include <cassert> #include <cstdint> // NOTE: Since the REPL itself could also include this runtime, extreme caution @@ -97,6 +98,7 @@ class REPL_EXTERNAL_VISIBILITY Value { REPL_BUILTIN_TYPES #undef X void *m_Ptr; + unsigned char m_RawBits[sizeof(long double) * 8]; // widest type }; public: @@ -111,7 +113,7 @@ public: }; Value() = default; - Value(Interpreter *In, void *Ty); + Value(const Interpreter *In, void *Ty); Value(const Value &RHS); Value(Value &&RHS) noexcept; Value &operator=(const Value &RHS); @@ -124,9 +126,7 @@ public: void dump() const; void clear(); - ASTContext &getASTContext(); const ASTContext &getASTContext() const; - Interpreter &getInterpreter(); const Interpreter &getInterpreter() const; QualType getType() const; @@ -140,6 +140,7 @@ public: void *getPtr() const; void setPtr(void *Ptr) { Data.m_Ptr = Ptr; } + void setRawBits(void *Ptr, unsigned NBits = sizeof(Storage)); #define X(type, name) \ void set##name(type Val) { Data.m_##name = Val; } \ @@ -193,7 +194,7 @@ protected: } }; - Interpreter *Interp = nullptr; + const Interpreter *Interp = nullptr; void *OpaqueType = nullptr; Storage Data; Kind ValueKind = K_Unspecified; @@ -205,6 +206,5 @@ template <> inline void *Value::as() const { return Data.m_Ptr; return (void *)as<uintptr_t>(); } - } // namespace clang #endif diff --git a/clang/include/clang/Lex/DependencyDirectivesScanner.h b/clang/include/clang/Lex/DependencyDirectivesScanner.h index acdc9e2..f9fec39 100644 --- a/clang/include/clang/Lex/DependencyDirectivesScanner.h +++ b/clang/include/clang/Lex/DependencyDirectivesScanner.h @@ -47,11 +47,10 @@ struct Token { bool is(tok::TokenKind K) const { return Kind == K; } bool isNot(tok::TokenKind K) const { return Kind != K; } - bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const { - return is(K1) || is(K2); - } - template <typename... Ts> bool isOneOf(tok::TokenKind K1, Ts... Ks) const { - return is(K1) || isOneOf(Ks...); + template <typename... Ts> bool isOneOf(Ts... Ks) const { + static_assert(sizeof...(Ts) > 0, + "requires at least one tok::TokenKind specified"); + return (is(Ks) || ...); } }; diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 4d82e20..71b0f8e 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -1847,6 +1847,10 @@ public: MacroExpansionInDirectivesOverride = true; } + void SetEnableMacroExpansion() { + DisableMacroExpansion = MacroExpansionInDirectivesOverride = false; + } + /// Peeks ahead N tokens and returns that token without consuming any /// tokens. /// diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h index ad66a26..a49bdfd 100644 --- a/clang/include/clang/Parse/ParseHLSLRootSignature.h +++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h @@ -30,7 +30,6 @@ namespace hlsl { class RootSignatureParser { public: RootSignatureParser(llvm::dxbc::RootSignatureVersion Version, - SmallVector<RootSignatureElement> &Elements, StringLiteral *Signature, Preprocessor &PP); /// Consumes tokens from the Lexer and constructs the in-memory @@ -40,6 +39,9 @@ public: /// Returns true if a parsing error is encountered. bool parse(); + /// Return all elements that have been parsed. + ArrayRef<RootSignatureElement> getElements() { return Elements; } + private: DiagnosticsEngine &getDiags() { return PP.getDiagnostics(); } @@ -226,7 +228,7 @@ private: private: llvm::dxbc::RootSignatureVersion Version; - SmallVector<RootSignatureElement> &Elements; + SmallVector<RootSignatureElement> Elements; StringLiteral *Signature; RootSignatureLexer Lexer; Preprocessor &PP; diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index a70335b..d34a414 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -1491,8 +1491,6 @@ class Sema; OverloadingResult BestViableFunctionImpl(Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best); - void PerfectViableFunction(Sema &S, SourceLocation Loc, - OverloadCandidateSet::iterator &Best); }; bool isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b331acb..423dcf9 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -834,6 +834,13 @@ enum class CCEKind { ///< message. }; +/// Enums for the diagnostics of target, target_version and target_clones. +namespace DiagAttrParams { +enum DiagType { Unsupported, Duplicate, Unknown }; +enum Specifier { None, CPU, Tune }; +enum AttrName { Target, TargetClones, TargetVersion }; +} // end namespace DiagAttrParams + void inferNoReturnAttr(Sema &S, const Decl *D); /// Sema - This implements semantic analysis and AST building for C. @@ -4922,13 +4929,6 @@ public: // handled later in the process, once we know how many exist. bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str); - /// Check Target Version attrs - bool checkTargetVersionAttr(SourceLocation Loc, Decl *D, StringRef Str); - bool checkTargetClonesAttrString( - SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal, - Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault, - SmallVectorImpl<SmallString<64>> &StringsBuffer); - ErrorAttr *mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI, StringRef NewUserDiagnostic); FormatAttr *mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI, @@ -9945,6 +9945,20 @@ private: VisibleModuleSet VisibleModules; + /// Whether we had imported any named modules. + bool HadImportedNamedModules = false; + /// The set of instantiations we need to check if they references TU-local + /// entity from TUs. This only makes sense if we imported any named modules. + llvm::SmallVector<std::pair<FunctionDecl *, SourceLocation>> + PendingCheckReferenceForTULocal; + /// Implement [basic.link]p18, which requires that we can't use TU-local + /// entities from other TUs (ignoring header units). + void checkReferenceToTULocalFromOtherTU(FunctionDecl *FD, + SourceLocation PointOfInstantiation); + /// Implement [basic.link]p17, which diagnose for non TU local exposure in + /// module interface or module partition. + void checkExposure(const TranslationUnitDecl *TU); + ///@} // diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h index 788a7ab..104992e 100644 --- a/clang/include/clang/Sema/SemaARM.h +++ b/clang/include/clang/Sema/SemaARM.h @@ -44,8 +44,8 @@ public: bool CheckImmediateArg(CallExpr *TheCall, unsigned CheckTy, unsigned ArgIdx, unsigned EltBitWidth, unsigned VecBitWidth); - bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, - unsigned MaxWidth); + bool CheckARMBuiltinExclusiveCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool PerformNeonImmChecks( @@ -91,6 +91,11 @@ public: /// Return true if the given vector types are lax-compatible SVE vector types, /// false otherwise. bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType); + + bool checkTargetVersionAttr(const StringRef Str, const SourceLocation Loc); + bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params, + SmallVectorImpl<SourceLocation> &Locs, + SmallVectorImpl<SmallString<64>> &NewParams); }; SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); diff --git a/clang/include/clang/Sema/SemaRISCV.h b/clang/include/clang/Sema/SemaRISCV.h index 8d2e1c6..844cc3c 100644 --- a/clang/include/clang/Sema/SemaRISCV.h +++ b/clang/include/clang/Sema/SemaRISCV.h @@ -55,6 +55,11 @@ public: bool DeclareAndesVectorBuiltins = false; std::unique_ptr<sema::RISCVIntrinsicManager> IntrinsicManager; + + bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc); + bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params, + SmallVectorImpl<SourceLocation> &Locs, + SmallVectorImpl<SmallString<64>> &NewParams); }; std::unique_ptr<sema::RISCVIntrinsicManager> diff --git a/clang/include/clang/Sema/SemaWasm.h b/clang/include/clang/Sema/SemaWasm.h index 2123e07..8c0639f 100644 --- a/clang/include/clang/Sema/SemaWasm.h +++ b/clang/include/clang/Sema/SemaWasm.h @@ -37,6 +37,7 @@ public: bool BuiltinWasmTableGrow(CallExpr *TheCall); bool BuiltinWasmTableFill(CallExpr *TheCall); bool BuiltinWasmTableCopy(CallExpr *TheCall); + bool BuiltinWasmTestFunctionPointerSignature(CallExpr *TheCall); WebAssemblyImportNameAttr * mergeImportNameAttr(Decl *D, const WebAssemblyImportNameAttr &AL); diff --git a/clang/include/clang/Sema/SemaX86.h b/clang/include/clang/Sema/SemaX86.h index b5a23f1..20783e3 100644 --- a/clang/include/clang/Sema/SemaX86.h +++ b/clang/include/clang/Sema/SemaX86.h @@ -37,6 +37,10 @@ public: void handleAnyInterruptAttr(Decl *D, const ParsedAttr &AL); void handleForceAlignArgPointerAttr(Decl *D, const ParsedAttr &AL); + + bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params, + SmallVectorImpl<SourceLocation> &Locs, + SmallVectorImpl<SmallString<64>> &NewParams); }; } // namespace clang diff --git a/clang/include/clang/Serialization/TypeBitCodes.def b/clang/include/clang/Serialization/TypeBitCodes.def index b8cde2e..613eb6a 100644 --- a/clang/include/clang/Serialization/TypeBitCodes.def +++ b/clang/include/clang/Serialization/TypeBitCodes.def @@ -69,5 +69,6 @@ TYPE_BIT_CODE(CountAttributed, COUNT_ATTRIBUTED, 57) TYPE_BIT_CODE(ArrayParameter, ARRAY_PARAMETER, 58) TYPE_BIT_CODE(HLSLAttributedResource, HLSLRESOURCE_ATTRIBUTED, 59) TYPE_BIT_CODE(HLSLInlineSpirv, HLSL_INLINE_SPIRV, 60) +TYPE_BIT_CODE(PredefinedSugar, PREDEFINED_SUGAR, 61) #undef TYPE_BIT_CODE diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 2234143..36196cd 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -206,21 +206,15 @@ def CallAndMessageChecker : Checker<"CallAndMessage">, Documentation<HasDocumentation>, Dependencies<[CallAndMessageModeling]>; -def DereferenceModeling : Checker<"DereferenceModeling">, - HelpText<"General support for dereference related checkers">, - Documentation<NotDocumented>, - Hidden; - def FixedAddressDereferenceChecker : Checker<"FixedAddressDereference">, HelpText<"Check for dereferences of fixed addresses">, - Documentation<HasDocumentation>, - Dependencies<[DereferenceModeling]>; + Documentation<HasDocumentation>; -def NullDereferenceChecker : Checker<"NullDereference">, - HelpText<"Check for dereferences of null pointers">, - Documentation<HasDocumentation>, - Dependencies<[DereferenceModeling]>; +def NullDereferenceChecker + : Checker<"NullDereference">, + HelpText<"Check for dereferences of null pointers">, + Documentation<HasDocumentation>; def NonNullParamChecker : Checker<"NonNullParamChecker">, HelpText<"Check for null pointers passed as arguments to a function whose " @@ -239,15 +233,11 @@ def UndefResultChecker : Checker<"UndefinedBinaryOperatorResult">, HelpText<"Check for undefined results of binary operators">, Documentation<HasDocumentation>; -def StackAddrEscapeBase : Checker<"StackAddrEscapeBase">, - HelpText<"Generate information about stack address escapes.">, - Documentation<NotDocumented>, - Hidden; - -def StackAddrEscapeChecker : Checker<"StackAddressEscape">, - HelpText<"Check that addresses to stack memory do not escape the function">, - Dependencies<[StackAddrEscapeBase]>, - Documentation<HasDocumentation>; +def StackAddrEscapeChecker + : Checker<"StackAddressEscape">, + HelpText< + "Check that addresses to stack memory do not escape the function">, + Documentation<HasDocumentation>; def DynamicTypePropagation : Checker<"DynamicTypePropagation">, HelpText<"Generate dynamic type information">, @@ -301,10 +291,11 @@ def DynamicTypeChecker Dependencies<[DynamicTypePropagation]>, Documentation<HasDocumentation>; -def StackAddrAsyncEscapeChecker : Checker<"StackAddressAsyncEscape">, - HelpText<"Check that addresses to stack memory do not escape the function">, - Dependencies<[StackAddrEscapeBase]>, - Documentation<HasDocumentation>; +def StackAddrAsyncEscapeChecker + : Checker<"StackAddressAsyncEscape">, + HelpText< + "Check that addresses to stack memory do not escape the function">, + Documentation<HasDocumentation>; def PthreadLockBase : Checker<"PthreadLockBase">, HelpText<"Helper registering multiple checks.">, @@ -1053,11 +1044,6 @@ def RetainCountBase : Checker<"RetainCountBase">, let ParentPackage = OSX in { -def NSOrCFErrorDerefChecker : Checker<"NSOrCFErrorDerefChecker">, - HelpText<"Implementation checker for NSErrorChecker and CFErrorChecker">, - Documentation<NotDocumented>, - Hidden; - def NumberObjectConversionChecker : Checker<"NumberObjectConversion">, HelpText<"Check for erroneous conversions of objects representing numbers " "into numbers">, @@ -1155,9 +1141,8 @@ def ObjCSuperCallChecker : Checker<"MissingSuperCall">, Documentation<NotDocumented>; def NSErrorChecker : Checker<"NSError">, - HelpText<"Check usage of NSError** parameters">, - Dependencies<[NSOrCFErrorDerefChecker]>, - Documentation<HasDocumentation>; + HelpText<"Check usage of NSError** parameters">, + Documentation<HasDocumentation>; def RetainCountChecker : Checker<"RetainCount">, HelpText<"Check for leaks and improper reference count management">, @@ -1259,9 +1244,8 @@ def CFRetainReleaseChecker : Checker<"CFRetainRelease">, Documentation<HasDocumentation>; def CFErrorChecker : Checker<"CFError">, - HelpText<"Check usage of CFErrorRef* parameters">, - Dependencies<[NSOrCFErrorDerefChecker]>, - Documentation<HasDocumentation>; + HelpText<"Check usage of CFErrorRef* parameters">, + Documentation<HasDocumentation>; } // end "osx.coreFoundation" @@ -1656,8 +1640,8 @@ def CloneChecker : Checker<"CloneChecker">, let ParentPackage = PortabilityOptIn in { def UnixAPIPortabilityChecker : Checker<"UnixAPI">, - HelpText<"Finds implementation-defined behavior in UNIX/Posix functions">, - Documentation<NotDocumented>; + HelpText<"Finds dynamic memory allocation with size zero">, + Documentation<HasDocumentation>; } // end optin.portability diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index 43dbfb1..da3efd7 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -38,29 +38,29 @@ // function clang_registerCheckers. For example: // // extern "C" -// void clang_registerCheckers (CheckerRegistry ®istry) { -// registry.addChecker<MainCallChecker>("example.MainCallChecker", -// "Disallows calls to functions called main"); +// void clang_registerCheckers(CheckerRegistry &Registry) { +// Registry.addChecker<MainCallChecker>( +// "example.MainCallChecker", +// "Disallows calls to functions called main"); // } // -// The first method argument is the full name of the checker, including its -// enclosing package. By convention, the registered name of a checker is the -// name of the associated class (the template argument). -// The second method argument is a short human-readable description of the -// checker. +// The first argument of this templated method is the full name of the checker +// (including its package), while the second argument is a short description +// that is printed by `-analyzer-checker-help`. // -// The clang_registerCheckers function may add any number of checkers to the -// registry. If any checkers require additional initialization, use the three- -// argument form of CheckerRegistry::addChecker. +// A plugin may register several separate checkers by calling `addChecker()` +// multiple times. If a checker requires custom registration functions (e.g. +// checker option handling) use the non-templated overload of `addChecker` that +// takes two callback functions as the first two parameters. // // To load a checker plugin, specify the full path to the dynamic library as // the argument to the -load option in the cc1 frontend. You can then enable // your custom checker using the -analyzer-checker: // -// clang -cc1 -load </path/to/plugin.dylib> -analyze -// -analyzer-checker=<example.MainCallChecker> +// clang -cc1 -load /path/to/plugin.dylib -analyze +// -analyzer-checker=example.MainCallChecker // -// For a complete working example, see examples/analyzer-plugin. +// For complete examples, see clang/lib/Analysis/plugins/SampleAnalyzer #ifndef CLANG_ANALYZER_API_VERSION_STRING // FIXME: The Clang version string is not particularly granular; @@ -108,30 +108,25 @@ private: mgr.template registerChecker<T>(); } - template <typename T> static bool returnTrue(const CheckerManager &mgr) { - return true; - } + static bool returnTrue(const CheckerManager &) { return true; } public: - /// Adds a checker to the registry. Use this non-templated overload when your - /// checker requires custom initialization. - void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction sfn, - StringRef FullName, StringRef Desc, StringRef DocsUri, - bool IsHidden); - - /// Adds a checker to the registry. Use this templated overload when your - /// checker does not require any custom initialization. - /// This function isn't really needed and probably causes more headaches than - /// the tiny convenience that it provides, but external plugins might use it, - /// and there isn't a strong incentive to remove it. + /// Adds a checker to the registry. + /// Use this for a checker defined in a plugin if it requires custom + /// registration functions (e.g. for handling checker options). + /// NOTE: As of now `DocsUri` is never queried from the checker registry. + void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction Sfn, + StringRef FullName, StringRef Desc, + StringRef DocsUri = "NoDocsUri", bool IsHidden = false); + + /// Adds a checker to the registry. + /// Use this for a checker defined in a plugin if it doesn't require custom + /// registration functions. template <class T> - void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri, - bool IsHidden = false) { - // Avoid MSVC's Compiler Error C2276: - // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx + void addChecker(StringRef FullName, StringRef Desc, + StringRef DocsUri = "NoDocsUri", bool IsHidden = false) { addChecker(&CheckerRegistry::initializeManager<CheckerManager, T>, - &CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri, - IsHidden); + &CheckerRegistry::returnTrue, FullName, Desc, DocsUri, IsHidden); } /// Makes the checker with the full name \p fullName depend on the checker diff --git a/clang/include/clang/Tooling/Inclusions/IncludeStyle.h b/clang/include/clang/Tooling/Inclusions/IncludeStyle.h index fba90d8..bf06061 100644 --- a/clang/include/clang/Tooling/Inclusions/IncludeStyle.h +++ b/clang/include/clang/Tooling/Inclusions/IncludeStyle.h @@ -126,8 +126,8 @@ struct IncludeStyle { /// * ``""`` means "arbitrary suffix" /// * ``"$"`` means "no suffix" /// - /// For example, if configured to ``"(_test)?$"``, then a header a.h would be seen - /// as the "main" include in both a.cc and a_test.cc. + /// For example, if configured to ``"(_test)?$"``, then a header a.h would be + /// seen as the "main" include in both a.cc and a_test.cc. /// \version 3.9 std::string IncludeIsMainRegex; |