diff --git ObsoleteFiles.inc ObsoleteFiles.inc index 9139ae81a948..8627a5e91a26 100644 --- ObsoleteFiles.inc +++ ObsoleteFiles.inc @@ -350,6 +350,7 @@ OLD_DIRS+=usr/lib/clang/13.0.0/lib OLD_DIRS+=usr/lib/clang/13.0.0 # 20220514: new libc++ import which bumps version from 13.0.0 to 14.0.0 +OLD_FILES+=usr/include/c++/v1/__function_like.h OLD_FILES+=usr/include/c++/v1/__memory/pointer_safety.h OLD_FILES+=usr/include/c++/v1/__utility/__decay_copy.h diff --git contrib/llvm-project/clang/include/clang/APINotes/Types.h contrib/llvm-project/clang/include/clang/APINotes/Types.h index 0d97e9ad8623..f741d9b91d76 100644 --- contrib/llvm-project/clang/include/clang/APINotes/Types.h +++ contrib/llvm-project/clang/include/clang/APINotes/Types.h @@ -133,7 +133,7 @@ class CommonTypeInfo : public CommonEntityInfo { llvm::Optional<std::string> NSErrorDomain; public: - CommonTypeInfo() : CommonEntityInfo() {} + CommonTypeInfo() {} const llvm::Optional<std::string> &getSwiftBridge() const { return SwiftBridge; @@ -208,10 +208,9 @@ class ObjCContextInfo : public CommonTypeInfo { public: ObjCContextInfo() - : CommonTypeInfo(), HasDefaultNullability(0), DefaultNullability(0), - HasDesignatedInits(0), SwiftImportAsNonGenericSpecified(false), - SwiftImportAsNonGeneric(false), SwiftObjCMembersSpecified(false), - SwiftObjCMembers(false) {} + : HasDefaultNullability(0), DefaultNullability(0), HasDesignatedInits(0), + SwiftImportAsNonGenericSpecified(false), SwiftImportAsNonGeneric(false), + SwiftObjCMembersSpecified(false), SwiftObjCMembers(false) {} /// Determine the default nullability for properties and methods of this /// class. @@ -309,7 +308,7 @@ class VariableInfo : public CommonEntityInfo { std::string Type; public: - VariableInfo() : CommonEntityInfo(), NullabilityAudited(false), Nullable(0) {} + VariableInfo() : NullabilityAudited(false), Nullable(0) {} llvm::Optional<NullabilityKind> getNullability() const { return NullabilityAudited ? llvm::Optional<NullabilityKind>( @@ -358,8 +357,7 @@ class ObjCPropertyInfo : public VariableInfo { public: ObjCPropertyInfo() - : VariableInfo(), SwiftImportAsAccessorsSpecified(false), - SwiftImportAsAccessors(false) {} + : SwiftImportAsAccessorsSpecified(false), SwiftImportAsAccessors(false) {} llvm::Optional<bool> getSwiftImportAsAccessors() const { return SwiftImportAsAccessorsSpecified @@ -423,8 +421,7 @@ class ParamInfo : public VariableInfo { public: ParamInfo() - : VariableInfo(), NoEscapeSpecified(false), NoEscape(false), - RawRetainCountConvention() {} + : NoEscapeSpecified(false), NoEscape(false), RawRetainCountConvention() {} llvm::Optional<bool> isNoEscape() const { if (!NoEscapeSpecified) @@ -514,7 +511,7 @@ public: std::vector<ParamInfo> Params; FunctionInfo() - : CommonEntityInfo(), NullabilityAudited(false), NumAdjustedNullable(0), + : NullabilityAudited(false), NumAdjustedNullable(0), RawRetainCountConvention() {} static unsigned getMaxNullabilityIndex() { @@ -607,8 +604,7 @@ public: /// Whether this is a required initializer. unsigned RequiredInit : 1; - ObjCMethodInfo() - : FunctionInfo(), DesignatedInit(false), RequiredInit(false) {} + ObjCMethodInfo() : DesignatedInit(false), RequiredInit(false) {} friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &); @@ -639,19 +635,19 @@ inline bool operator!=(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) { /// Describes API notes data for a global variable. class GlobalVariableInfo : public VariableInfo { public: - GlobalVariableInfo() : VariableInfo() {} + GlobalVariableInfo() {} }; /// Describes API notes data for a global function. class GlobalFunctionInfo : public FunctionInfo { public: - GlobalFunctionInfo() : FunctionInfo() {} + GlobalFunctionInfo() {} }; /// Describes API notes data for an enumerator. class EnumConstantInfo : public CommonEntityInfo { public: - EnumConstantInfo() : CommonEntityInfo() {} + EnumConstantInfo() {} }; /// Describes API notes data for a tag. @@ -662,7 +658,7 @@ class TagInfo : public CommonTypeInfo { public: llvm::Optional<EnumExtensibilityKind> EnumExtensibility; - TagInfo() : CommonTypeInfo(), HasFlagEnum(0), IsFlagEnum(0) {} + TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {} llvm::Optional<bool> isFlagEnum() const { if (HasFlagEnum) @@ -706,7 +702,7 @@ class TypedefInfo : public CommonTypeInfo { public: llvm::Optional<SwiftNewTypeKind> SwiftWrapper; - TypedefInfo() : CommonTypeInfo() {} + TypedefInfo() {} TypedefInfo &operator|=(const TypedefInfo &RHS) { static_cast<CommonTypeInfo &>(*this) |= RHS; diff --git contrib/llvm-project/clang/include/clang/AST/ASTConcept.h contrib/llvm-project/clang/include/clang/AST/ASTConcept.h index aba18b060b02..25e00860060f 100644 --- contrib/llvm-project/clang/include/clang/AST/ASTConcept.h +++ contrib/llvm-project/clang/include/clang/AST/ASTConcept.h @@ -22,7 +22,6 @@ namespace clang { class ConceptDecl; -class ConceptSpecializationExpr; /// The result of a constraint satisfaction check, containing the necessary /// information to diagnose an unsatisfied constraint. @@ -123,17 +122,16 @@ protected: const ASTTemplateArgumentListInfo *ArgsAsWritten; public: - ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten) : - NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc), - ConceptName(ConceptNameInfo), FoundDecl(FoundDecl), - NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {} + const ASTTemplateArgumentListInfo *ArgsAsWritten) + : NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc), + ConceptName(ConceptNameInfo), FoundDecl(FoundDecl), + NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {} - ConceptReference() : NestedNameSpec(), TemplateKWLoc(), ConceptName(), - FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {} + ConceptReference() + : FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {} const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { return NestedNameSpec; diff --git contrib/llvm-project/clang/include/clang/AST/ASTContext.h contrib/llvm-project/clang/include/clang/AST/ASTContext.h index 63f2c948c79b..f39ce14bc82c 100644 --- contrib/llvm-project/clang/include/clang/AST/ASTContext.h +++ contrib/llvm-project/clang/include/clang/AST/ASTContext.h @@ -99,15 +99,12 @@ class CXXMethodDecl; class CXXRecordDecl; class DiagnosticsEngine; class ParentMapContext; -class DynTypedNode; class DynTypedNodeList; class Expr; enum class FloatModeKind; class GlobalDecl; -class ItaniumMangleContext; class MangleContext; class MangleNumberingContext; -class MaterializeTemporaryExpr; class MemberSpecializationInfo; class Module; struct MSGuidDeclParts; @@ -126,7 +123,6 @@ class ObjCTypeParamDecl; class OMPTraitInfo; struct ParsedTargetAttr; class Preprocessor; -class Stmt; class StoredDeclsMap; class TargetAttr; class TargetInfo; @@ -2626,6 +2622,18 @@ public: /// template. bool hasSameTemplateName(TemplateName X, TemplateName Y); + /// Determine whether the two declarations refer to the same entity. + bool isSameEntity(NamedDecl *X, NamedDecl *Y); + + /// Determine whether two template parameter lists are similar enough + /// that they may be used in declarations of the same template. + bool isSameTemplateParameterList(TemplateParameterList *X, + TemplateParameterList *Y); + + /// Determine whether two template parameters are similar enough + /// that they may be used in declarations of the same template. + bool isSameTemplateParameter(NamedDecl *X, NamedDecl *Y); + /// Retrieve the "canonical" template argument. /// /// The canonical template argument is the simplest template argument @@ -2730,13 +2738,9 @@ public: QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize, QualType typeDomain) const; - unsigned getTargetAddressSpace(QualType T) const { - return getTargetAddressSpace(T.getQualifiers()); - } + unsigned getTargetAddressSpace(QualType T) const; - unsigned getTargetAddressSpace(Qualifiers Q) const { - return getTargetAddressSpace(Q.getAddressSpace()); - } + unsigned getTargetAddressSpace(Qualifiers Q) const; unsigned getTargetAddressSpace(LangAS AS) const; diff --git contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h index 918c2b9e350c..2dbc44c5dcd4 100644 --- contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h +++ contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h @@ -21,7 +21,6 @@ namespace clang { -class ASTContext; class NamedDecl; class DeclContext; diff --git contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h index 442039044cfe..b2fc2d2c7e4b 100644 --- contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h +++ contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CLANG_AST_ABSTRACTBASICREADER_H -#define CLANG_AST_ABSTRACTBASICREADER_H +#ifndef LLVM_CLANG_AST_ABSTRACTBASICREADER_H +#define LLVM_CLANG_AST_ABSTRACTBASICREADER_H #include "clang/AST/DeclTemplate.h" diff --git contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h index 75aef734ba9b..41772ba0f63c 100644 --- contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h +++ contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CLANG_AST_ABSTRACTBASICWRITER_H -#define CLANG_AST_ABSTRACTBASICWRITER_H +#ifndef LLVM_CLANG_AST_ABSTRACTBASICWRITER_H +#define LLVM_CLANG_AST_ABSTRACTBASICWRITER_H #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" diff --git contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h index 9fea7b26f678..c9162b1779bc 100644 --- contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h +++ contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CLANG_AST_ABSTRACTTYPEREADER_H -#define CLANG_AST_ABSTRACTTYPEREADER_H +#ifndef LLVM_CLANG_AST_ABSTRACTTYPEREADER_H +#define LLVM_CLANG_AST_ABSTRACTTYPEREADER_H #include "clang/AST/Type.h" #include "clang/AST/AbstractBasicReader.h" diff --git contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h index a63cb0be099d..62006ef0f26e 100644 --- contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h +++ contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CLANG_AST_ABSTRACTTYPEWRITER_H -#define CLANG_AST_ABSTRACTTYPEWRITER_H +#ifndef LLVM_CLANG_AST_ABSTRACTTYPEWRITER_H +#define LLVM_CLANG_AST_ABSTRACTTYPEWRITER_H #include "clang/AST/Type.h" #include "clang/AST/AbstractBasicWriter.h" diff --git contrib/llvm-project/clang/include/clang/AST/Attr.h contrib/llvm-project/clang/include/clang/AST/Attr.h index 6366d6e8837e..070e160d6517 100644 --- contrib/llvm-project/clang/include/clang/AST/Attr.h +++ contrib/llvm-project/clang/include/clang/AST/Attr.h @@ -34,12 +34,7 @@ namespace clang { class ASTContext; class AttributeCommonInfo; -class IdentifierInfo; -class ObjCInterfaceDecl; -class Expr; -class QualType; class FunctionDecl; -class TypeSourceInfo; class OMPTraitInfo; /// Attr - This represents one attribute. diff --git contrib/llvm-project/clang/include/clang/AST/AttrIterator.h contrib/llvm-project/clang/include/clang/AST/AttrIterator.h index 78ce9314a2bb..66571e1cf0b8 100644 --- contrib/llvm-project/clang/include/clang/AST/AttrIterator.h +++ contrib/llvm-project/clang/include/clang/AST/AttrIterator.h @@ -22,7 +22,6 @@ namespace clang { -class ASTContext; class Attr; /// AttrVec - A vector of Attr, which is how they are stored on the AST. diff --git contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def index 9b270682f8cf..cdf0804680ad 100644 --- contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def +++ contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def @@ -112,6 +112,9 @@ FIELD(HasVariantMembers, 1, NO_MERGE) /// True if there no non-field members declared by the user. FIELD(HasOnlyCMembers, 1, NO_MERGE) +/// True if there is an '__init' method defined by the user. +FIELD(HasInitMethod, 1, NO_MERGE) + /// True if any field has an in-class initializer, including those /// within anonymous unions or structs. FIELD(HasInClassInitializer, 1, NO_MERGE) diff --git contrib/llvm-project/clang/include/clang/AST/Comment.h contrib/llvm-project/clang/include/clang/AST/Comment.h index 4184e103206d..5ecc35791b7b 100644 --- contrib/llvm-project/clang/include/clang/AST/Comment.h +++ contrib/llvm-project/clang/include/clang/AST/Comment.h @@ -424,19 +424,13 @@ public: Attribute() { } - Attribute(SourceLocation NameLocBegin, StringRef Name) : - NameLocBegin(NameLocBegin), Name(Name), - EqualsLoc(SourceLocation()), - ValueRange(SourceRange()), Value(StringRef()) - { } + Attribute(SourceLocation NameLocBegin, StringRef Name) + : NameLocBegin(NameLocBegin), Name(Name), EqualsLoc(SourceLocation()) {} Attribute(SourceLocation NameLocBegin, StringRef Name, - SourceLocation EqualsLoc, - SourceRange ValueRange, StringRef Value) : - NameLocBegin(NameLocBegin), Name(Name), - EqualsLoc(EqualsLoc), - ValueRange(ValueRange), Value(Value) - { } + SourceLocation EqualsLoc, SourceRange ValueRange, StringRef Value) + : NameLocBegin(NameLocBegin), Name(Name), EqualsLoc(EqualsLoc), + ValueRange(ValueRange), Value(Value) {} SourceLocation getNameLocEnd() const { return NameLocBegin.getLocWithOffset(Name.size()); diff --git contrib/llvm-project/clang/include/clang/AST/CommentLexer.h contrib/llvm-project/clang/include/clang/AST/CommentLexer.h index 94f778501e75..9aa1681cb2c5 100644 --- contrib/llvm-project/clang/include/clang/AST/CommentLexer.h +++ contrib/llvm-project/clang/include/clang/AST/CommentLexer.h @@ -320,6 +320,9 @@ private: /// Eat string matching regexp \code \s*\* \endcode. void skipLineStartingDecorations(); + /// Skip over pure text. + const char *skipTextToken(); + /// Lex comment text, including commands if ParseCommands is set to true. void lexCommentText(Token &T); diff --git contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h index 8db09e6b57d0..cb545aff51f8 100644 --- contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h +++ contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H -#define LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H +#ifndef LLVM_CLANG_AST_COMPUTEDEPENDENCE_H +#define LLVM_CLANG_AST_COMPUTEDEPENDENCE_H #include "clang/AST/DependenceFlags.h" #include "clang/Basic/ExceptionSpecificationType.h" diff --git contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h index 34df8ce1309e..4f8343efad16 100644 --- contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h +++ contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H -#define LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H +#ifndef LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H +#define LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H #include <cassert> @@ -71,4 +71,4 @@ private: } // end namespace clang -#endif // LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H +#endif // LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H diff --git contrib/llvm-project/clang/include/clang/AST/Decl.h contrib/llvm-project/clang/include/clang/AST/Decl.h index 2c92571325c8..5ebd7e5d0d36 100644 --- contrib/llvm-project/clang/include/clang/AST/Decl.h +++ contrib/llvm-project/clang/include/clang/AST/Decl.h @@ -53,7 +53,6 @@ namespace clang { class ASTContext; struct ASTTemplateArgumentListInfo; -class Attr; class CompoundStmt; class DependentFunctionTemplateSpecializationInfo; class EnumDecl; @@ -74,7 +73,6 @@ class TemplateArgumentList; class TemplateArgumentListInfo; class TemplateParameterList; class TypeAliasTemplateDecl; -class TypeLoc; class UnresolvedSetImpl; class VarTemplateDecl; diff --git contrib/llvm-project/clang/include/clang/AST/DeclBase.h contrib/llvm-project/clang/include/clang/AST/DeclBase.h index 2a0a19597391..06d2f17d1430 100644 --- contrib/llvm-project/clang/include/clang/AST/DeclBase.h +++ contrib/llvm-project/clang/include/clang/AST/DeclBase.h @@ -52,14 +52,8 @@ enum Linkage : unsigned char; class LinkageSpecDecl; class Module; class NamedDecl; -class ObjCCategoryDecl; -class ObjCCategoryImplDecl; class ObjCContainerDecl; -class ObjCImplDecl; -class ObjCImplementationDecl; -class ObjCInterfaceDecl; class ObjCMethodDecl; -class ObjCProtocolDecl; struct PrintingPolicy; class RecordDecl; class SourceManager; @@ -613,6 +607,20 @@ public: return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate; } + /// Whether this declaration was exported in a lexical context. + /// e.g.: + /// + /// export namespace A { + /// void f1(); // isInExportDeclContext() == true + /// } + /// void A::f1(); // isInExportDeclContext() == false + /// + /// namespace B { + /// void f2(); // isInExportDeclContext() == false + /// } + /// export void B::f2(); // isInExportDeclContext() == true + bool isInExportDeclContext() const; + /// Return true if this declaration has an attribute which acts as /// definition of the entity, such as 'alias' or 'ifunc'. bool hasDefiningAttr() const; diff --git contrib/llvm-project/clang/include/clang/AST/DeclCXX.h contrib/llvm-project/clang/include/clang/AST/DeclCXX.h index cc7bfc86a521..2833df0505da 100644 --- contrib/llvm-project/clang/include/clang/AST/DeclCXX.h +++ contrib/llvm-project/clang/include/clang/AST/DeclCXX.h @@ -64,7 +64,6 @@ class CXXFinalOverriderMap; class CXXIndirectPrimaryBaseSet; class CXXMethodDecl; class DecompositionDecl; -class DiagnosticBuilder; class FriendDecl; class FunctionTemplateDecl; class IdentifierInfo; @@ -1140,6 +1139,9 @@ public: /// \note This does NOT include a check for union-ness. bool isEmpty() const { return data().Empty; } + void setInitMethod(bool Val) { data().HasInitMethod = Val; } + bool hasInitMethod() const { return data().HasInitMethod; } + bool hasPrivateFields() const { return data().HasPrivateFields; } @@ -3291,7 +3293,7 @@ class BaseUsingDecl : public NamedDecl { protected: BaseUsingDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) - : NamedDecl(DK, DC, L, N), FirstUsingShadow(nullptr, 0) {} + : NamedDecl(DK, DC, L, N), FirstUsingShadow(nullptr, false) {} private: void anchor() override; diff --git contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h index 9899fc29b82d..903cdb7bfcc8 100644 --- contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h +++ contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h @@ -90,7 +90,7 @@ public: StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) { RHS.Data.setPointer(nullptr); - RHS.Data.setInt(0); + RHS.Data.setInt(false); } void MaybeDeallocList() { @@ -114,7 +114,7 @@ public: Data = RHS.Data; RHS.Data.setPointer(nullptr); - RHS.Data.setInt(0); + RHS.Data.setInt(false); return *this; } @@ -142,7 +142,7 @@ public: } void setHasExternalDecls() { - Data.setInt(1); + Data.setInt(true); } void remove(NamedDecl *D) { @@ -155,7 +155,7 @@ public: erase_if([](NamedDecl *ND) { return ND->isFromASTFile(); }); // Don't have any pending external decls any more. - Data.setInt(0); + Data.setInt(false); } void replaceExternalDecls(ArrayRef<NamedDecl*> Decls) { @@ -171,7 +171,7 @@ public: }); // Don't have any pending external decls any more. - Data.setInt(0); + Data.setInt(false); if (Decls.empty()) return; diff --git contrib/llvm-project/clang/include/clang/AST/DeclObjC.h contrib/llvm-project/clang/include/clang/AST/DeclObjC.h index 79ec1d6e5c3c..110b7dc0c6f2 100644 --- contrib/llvm-project/clang/include/clang/AST/DeclObjC.h +++ contrib/llvm-project/clang/include/clang/AST/DeclObjC.h @@ -779,17 +779,13 @@ private: LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI), PropertyAttributes(ObjCPropertyAttribute::kind_noattr), PropertyAttributesAsWritten(ObjCPropertyAttribute::kind_noattr), - PropertyImplementation(propControl), GetterName(Selector()), - SetterName(Selector()) {} + PropertyImplementation(propControl) {} public: - static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - IdentifierInfo *Id, SourceLocation AtLocation, - SourceLocation LParenLocation, - QualType T, - TypeSourceInfo *TSI, - PropertyControl propControl = None); + static ObjCPropertyDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, + SourceLocation AtLocation, SourceLocation LParenLocation, QualType T, + TypeSourceInfo *TSI, PropertyControl propControl = None); static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1075,6 +1071,9 @@ public: bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const; ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; + ObjCPropertyDecl *getProperty(const IdentifierInfo *Id, + bool IsInstance) const; + ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const; diff --git contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h index 5f03bce6e9a8..42c97204a613 100644 --- contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h +++ contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_AST_DECLOBJC_COMMON_H -#define LLVM_CLANG_AST_DECLOBJC_COMMON_H +#ifndef LLVM_CLANG_AST_DECLOBJCCOMMON_H +#define LLVM_CLANG_AST_DECLOBJCCOMMON_H namespace clang { @@ -52,4 +52,4 @@ enum { } // namespace clang -#endif // LLVM_CLANG_AST_DECLOBJC_COMMON_H +#endif // LLVM_CLANG_AST_DECLOBJCCOMMON_H diff --git contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h index f7a2e3146d06..d216b359816e 100755 --- contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h +++ contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h @@ -498,7 +498,7 @@ private: TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs, const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo) - : Function(FD, MSInfo ? 1 : 0), Template(Template, TSK - 1), + : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1), TemplateArguments(TemplateArgs), TemplateArgumentsAsWritten(TemplateArgsAsWritten), PointOfInstantiation(POI) { diff --git contrib/llvm-project/clang/include/clang/AST/DeclarationName.h contrib/llvm-project/clang/include/clang/AST/DeclarationName.h index 38da6fc727fb..0762e0a478ea 100644 --- contrib/llvm-project/clang/include/clang/AST/DeclarationName.h +++ contrib/llvm-project/clang/include/clang/AST/DeclarationName.h @@ -34,11 +34,9 @@ class ASTContext; template <typename> class CanQual; class DeclarationName; class DeclarationNameTable; -class MultiKeywordSelector; struct PrintingPolicy; class TemplateDecl; class TypeSourceInfo; -class UsingDirectiveDecl; using CanQualType = CanQual<Type>; diff --git contrib/llvm-project/clang/include/clang/AST/Expr.h contrib/llvm-project/clang/include/clang/AST/Expr.h index 54ad1934e477..ce5280d77c36 100644 --- contrib/llvm-project/clang/include/clang/AST/Expr.h +++ contrib/llvm-project/clang/include/clang/AST/Expr.h @@ -2387,7 +2387,7 @@ public: /// Create an offsetof node that refers into a C++ base class. explicit OffsetOfNode(const CXXBaseSpecifier *Base) - : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {} + : Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {} /// Determine what kind of offsetof node this is. Kind getKind() const { return static_cast<Kind>(Data & Mask); } diff --git contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h index 1544c498ef66..6849b65b71c0 100644 --- contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h +++ contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h @@ -275,12 +275,12 @@ public: friend ASTStmtWriter; /// \brief No return type requirement was specified. - ReturnTypeRequirement() : TypeConstraintInfo(nullptr, 0) {} + ReturnTypeRequirement() : TypeConstraintInfo(nullptr, false) {} /// \brief A return type requirement was specified but it was a /// substitution failure. ReturnTypeRequirement(SubstitutionDiagnostic *SubstDiag) : - TypeConstraintInfo(SubstDiag, 0) {} + TypeConstraintInfo(SubstDiag, false) {} /// \brief A 'type constraint' style return type requirement. /// \param TPL an invented template parameter list containing a single @@ -413,12 +413,12 @@ public: friend ASTStmtWriter; NestedRequirement(SubstitutionDiagnostic *SubstDiag) : - Requirement(RK_Nested, /*Dependent=*/false, + Requirement(RK_Nested, /*IsDependent=*/false, /*ContainsUnexpandedParameterPack*/false, - /*Satisfied=*/false), Value(SubstDiag) {} + /*IsSatisfied=*/false), Value(SubstDiag) {} NestedRequirement(Expr *Constraint) : - Requirement(RK_Nested, /*Dependent=*/true, + Requirement(RK_Nested, /*IsDependent=*/true, Constraint->containsUnexpandedParameterPack()), Value(Constraint) { assert(Constraint->isInstantiationDependent() && diff --git contrib/llvm-project/clang/include/clang/AST/ExprObjC.h contrib/llvm-project/clang/include/clang/AST/ExprObjC.h index b0f057dbaa02..3b7ad8662ad9 100644 --- contrib/llvm-project/clang/include/clang/AST/ExprObjC.h +++ contrib/llvm-project/clang/include/clang/AST/ExprObjC.h @@ -1706,7 +1706,7 @@ public: /// This may be '*', in which case this should fold to true. bool hasVersion() const { return !VersionToCheck.empty(); } - VersionTuple getVersion() { return VersionToCheck; } + VersionTuple getVersion() const { return VersionToCheck; } child_range children() { return child_range(child_iterator(), child_iterator()); diff --git contrib/llvm-project/clang/include/clang/AST/FormatString.h contrib/llvm-project/clang/include/clang/AST/FormatString.h index 8c944451f796..d7933382f13d 100644 --- contrib/llvm-project/clang/include/clang/AST/FormatString.h +++ contrib/llvm-project/clang/include/clang/AST/FormatString.h @@ -15,8 +15,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H -#define LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H +#ifndef LLVM_CLANG_AST_FORMATSTRING_H +#define LLVM_CLANG_AST_FORMATSTRING_H #include "clang/AST/CanonicalType.h" @@ -332,11 +332,11 @@ public: unsigned amountLength, bool usesPositionalArg) : start(amountStart), length(amountLength), hs(howSpecified), amt(amount), - UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {} + UsesPositionalArg(usesPositionalArg), UsesDotPrefix(false) {} OptionalAmount(bool valid = true) : start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0), - UsesPositionalArg(0), UsesDotPrefix(0) {} + UsesPositionalArg(false), UsesDotPrefix(false) {} explicit OptionalAmount(unsigned Amount) : start(nullptr), length(0), hs(Constant), amt(Amount), @@ -726,7 +726,8 @@ public: virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, - unsigned specifierLen) { + unsigned specifierLen, + const TargetInfo &Target) { return true; } diff --git contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h index e42f0449f6db..054220b8a32c 100644 --- contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h +++ contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H -#define LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H +#ifndef LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H +#define LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/LLVM.h" @@ -160,4 +160,4 @@ private: } // end namespace clang -#endif // LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H +#endif // LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H diff --git contrib/llvm-project/clang/include/clang/AST/LocInfoType.h contrib/llvm-project/clang/include/clang/AST/LocInfoType.h index 7e845ad03587..876c7deeceb9 100644 --- contrib/llvm-project/clang/include/clang/AST/LocInfoType.h +++ contrib/llvm-project/clang/include/clang/AST/LocInfoType.h @@ -10,8 +10,8 @@ // source-location information. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_LOCINFOTYPE_H -#define LLVM_CLANG_SEMA_LOCINFOTYPE_H +#ifndef LLVM_CLANG_AST_LOCINFOTYPE_H +#define LLVM_CLANG_AST_LOCINFOTYPE_H #include "clang/AST/Type.h" @@ -54,4 +54,4 @@ public: } // end namespace clang -#endif // LLVM_CLANG_SEMA_LOCINFOTYPE_H +#endif // LLVM_CLANG_AST_LOCINFOTYPE_H diff --git contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h index eb33759682d6..a4a6ce4c2708 100644 --- contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h +++ contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h @@ -21,9 +21,7 @@ namespace clang { class BlockDecl; class CXXMethodDecl; -class IdentifierInfo; class TagDecl; -class Type; class VarDecl; /// Keeps track of the mangled names of lambda expressions and block diff --git contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h index c95516538ad1..cf320c8a478a 100644 --- contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h +++ contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H -#define LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H +#ifndef LLVM_CLANG_AST_NONTRIVIALTYPEVISITOR_H +#define LLVM_CLANG_AST_NONTRIVIALTYPEVISITOR_H #include "clang/AST/Type.h" diff --git contrib/llvm-project/clang/include/clang/AST/OSLog.h contrib/llvm-project/clang/include/clang/AST/OSLog.h index c24e79ce6da0..3772597e2616 100644 --- contrib/llvm-project/clang/include/clang/AST/OSLog.h +++ contrib/llvm-project/clang/include/clang/AST/OSLog.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H -#define LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H +#ifndef LLVM_CLANG_AST_OSLOG_H +#define LLVM_CLANG_AST_OSLOG_H #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" diff --git contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h index 3fd1b6d30080..3ecc1d40fafc 100644 --- contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h +++ contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h @@ -32,6 +32,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Frontend/OpenMP/OMPAssume.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" #include "llvm/Frontend/OpenMP/OMPContext.h" #include "llvm/Support/Casting.h" diff --git contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h index 899bbcb3be45..82df031d4126 100644 --- contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h +++ contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h @@ -22,7 +22,6 @@ namespace clang { class ASTContext; class Decl; -class SourceManager; /// PrettyDeclStackTraceEntry - If a crash occurs in the parser while /// parsing something related to a declaration, include that diff --git contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h index f6816e938f2a..fd40328d8dcf 100644 --- contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h +++ contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h @@ -20,9 +20,7 @@ namespace clang { class DeclContext; class LangOptions; -class SourceManager; class Stmt; -class TagDecl; class PrinterHelper { public: @@ -75,7 +73,8 @@ struct PrintingPolicy { MSVCFormatting(false), ConstantsAsWritten(false), SuppressImplicitBase(false), FullyQualifiedName(false), PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true), - UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false) {} + UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false), + CleanUglifiedParameters(false) {} /// Adjust this printing policy for cases where it's known that we're /// printing C++ code (for instance, if AST dumping reaches a C++-only @@ -282,6 +281,11 @@ struct PrintingPolicy { /// parameters. unsigned AlwaysIncludeTypeForTemplateArgument : 1; + /// Whether to strip underscores when printing reserved parameter names. + /// e.g. std::vector<class _Tp> becomes std::vector<class Tp>. + /// This only affects parameter names, and so describes a compatible API. + unsigned CleanUglifiedParameters : 1; + /// Callbacks to use to allow the behavior of printing to be customized. const PrintingCallbacks *Callbacks = nullptr; }; diff --git contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h index 8313e0441be5..daa86cda2d99 100644 --- contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h +++ contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h @@ -89,4 +89,4 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx, bool WithGlobalNsPrefix = false); } // end namespace TypeName } // end namespace clang -#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H +#endif // LLVM_CLANG_AST_QUALTYPENAMES_H diff --git contrib/llvm-project/clang/include/clang/AST/TemplateBase.h contrib/llvm-project/clang/include/clang/AST/TemplateBase.h index fa27a12cfbb9..e8064121d279 100644 --- contrib/llvm-project/clang/include/clang/AST/TemplateBase.h +++ contrib/llvm-project/clang/include/clang/AST/TemplateBase.h @@ -52,7 +52,6 @@ template <> struct PointerLikeTypeTraits<clang::Expr *> { namespace clang { class ASTContext; -class DiagnosticBuilder; class Expr; struct PrintingPolicy; class TypeSourceInfo; diff --git contrib/llvm-project/clang/include/clang/AST/TemplateName.h contrib/llvm-project/clang/include/clang/AST/TemplateName.h index 2befb5c1b45e..44080a7f56d4 100644 --- contrib/llvm-project/clang/include/clang/AST/TemplateName.h +++ contrib/llvm-project/clang/include/clang/AST/TemplateName.h @@ -26,14 +26,12 @@ namespace clang { class ASTContext; class DependentTemplateName; -class DiagnosticBuilder; class IdentifierInfo; class NamedDecl; class NestedNameSpecifier; enum OverloadedOperatorKind : int; class OverloadedTemplateStorage; class AssumedTemplateStorage; -class PartialDiagnostic; struct PrintingPolicy; class QualifiedTemplateName; class SubstTemplateTemplateParmPackStorage; diff --git contrib/llvm-project/clang/include/clang/AST/TypeLoc.h contrib/llvm-project/clang/include/clang/AST/TypeLoc.h index 7a036836e8c4..8cfa579a22da 100644 --- contrib/llvm-project/clang/include/clang/AST/TypeLoc.h +++ contrib/llvm-project/clang/include/clang/AST/TypeLoc.h @@ -1994,12 +1994,35 @@ public: void initializeLocal(ASTContext &Context, SourceLocation Loc); }; -// FIXME: location of the 'decltype' and parens. -class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, - DecltypeTypeLoc, - DecltypeType> { +// decltype(expression) abc; +// ~~~~~~~~ DecltypeLoc +// ~ RParenLoc +// FIXME: add LParenLoc, it is tricky to support due to the limitation of +// annotated-decltype token. +struct DecltypeTypeLocInfo { + SourceLocation DecltypeLoc; + SourceLocation RParenLoc; +}; +class DecltypeTypeLoc + : public ConcreteTypeLoc<UnqualTypeLoc, DecltypeTypeLoc, DecltypeType, + DecltypeTypeLocInfo> { public: Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } + + SourceLocation getDecltypeLoc() const { return getLocalData()->DecltypeLoc; } + void setDecltypeLoc(SourceLocation Loc) { getLocalData()->DecltypeLoc = Loc; } + + SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } + void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } + + SourceRange getLocalSourceRange() const { + return SourceRange(getDecltypeLoc(), getRParenLoc()); + } + + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + setDecltypeLoc(Loc); + setRParenLoc(Loc); + } }; struct UnaryTransformTypeLocInfo { @@ -2058,6 +2081,11 @@ struct AutoTypeLocInfo : TypeSpecLocInfo { NamedDecl *FoundDecl; SourceLocation LAngleLoc; SourceLocation RAngleLoc; + + // For decltype(auto). + SourceLocation RParenLoc; + + // Followed by a TemplateArgumentLocInfo[] }; class AutoTypeLoc @@ -2070,6 +2098,10 @@ public: return getTypePtr()->getKeyword(); } + bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); } + SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } + void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } + bool isConstrained() const { return getTypePtr()->isConstrained(); } @@ -2150,16 +2182,13 @@ public: } SourceRange getLocalSourceRange() const { - return{ - isConstrained() - ? (getNestedNameSpecifierLoc() - ? getNestedNameSpecifierLoc().getBeginLoc() - : (getTemplateKWLoc().isValid() - ? getTemplateKWLoc() - : getConceptNameLoc())) - : getNameLoc(), - getNameLoc() - }; + return {isConstrained() + ? (getNestedNameSpecifierLoc() + ? getNestedNameSpecifierLoc().getBeginLoc() + : (getTemplateKWLoc().isValid() ? getTemplateKWLoc() + : getConceptNameLoc())) + : getNameLoc(), + isDecltypeAuto() ? getRParenLoc() : getNameLoc()}; } void copy(AutoTypeLoc Loc) { diff --git contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h index c75aa0785a63..17b47f6ab96b 100644 --- contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h +++ contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h @@ -121,7 +121,7 @@ public: void setAccess(iterator I, AccessSpecifier AS) { I.I->setAccess(AS); } void clear() { decls().clear(); } - void set_size(unsigned N) { decls().set_size(N); } + void truncate(unsigned N) { decls().truncate(N); } bool empty() const { return decls().empty(); } unsigned size() const { return decls().size(); } diff --git contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h index 55cce324b436..86bd44091b59 100644 --- contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h +++ contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -3725,10 +3725,9 @@ AST_MATCHER_P(ObjCMessageExpr, hasReceiver, internal::Matcher<Expr>, /// \endcode AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName) { Selector Sel = Node.getSelector(); - return BaseName.compare(Sel.getAsString()) == 0; + return BaseName == Sel.getAsString(); } - /// Matches when at least one of the supplied string equals to the /// Selector.getAsString() /// @@ -5171,6 +5170,25 @@ AST_POLYMORPHIC_MATCHER(isNoThrow, return FnTy->isNothrow(); } +/// Matches consteval function declarations and if consteval/if ! consteval +/// statements. +/// +/// Given: +/// \code +/// consteval int a(); +/// void b() { if consteval {} } +/// void c() { if ! consteval {} } +/// void d() { if ! consteval {} else {} } +/// \endcode +/// functionDecl(isConsteval()) +/// matches the declaration of "int a()". +/// ifStmt(isConsteval()) +/// matches the if statement in "void b()", "void c()", "void d()". +AST_POLYMORPHIC_MATCHER(isConsteval, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, IfStmt)) { + return Node.isConsteval(); +} + /// Matches constexpr variable and function declarations, /// and if constexpr. /// @@ -5193,6 +5211,23 @@ AST_POLYMORPHIC_MATCHER(isConstexpr, return Node.isConstexpr(); } +/// Matches constinit variable declarations. +/// +/// Given: +/// \code +/// constinit int foo = 42; +/// constinit const char* bar = "bar"; +/// int baz = 42; +/// [[clang::require_constant_initialization]] int xyz = 42; +/// \endcode +/// varDecl(isConstinit()) +/// matches the declaration of `foo` and `bar`, but not `baz` and `xyz`. +AST_MATCHER(VarDecl, isConstinit) { + if (const auto *CIA = Node.getAttr<ConstInitAttr>()) + return CIA->isConstinit(); + return false; +} + /// Matches selection statements with initializer. /// /// Given: diff --git contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h index 10625311c1a5..3f6f364d6505 100644 --- contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h +++ contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h @@ -40,7 +40,7 @@ struct SourceRange { /// A VariantValue instance annotated with its parser context. struct ParserValue { - ParserValue() : Text(), Range(), Value() {} + ParserValue() {} StringRef Text; SourceRange Range; VariantValue Value; @@ -186,4 +186,4 @@ private: } // namespace ast_matchers } // namespace clang -#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H +#endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H diff --git contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Parser.h contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Parser.h index af370d83782a..26e321c98ff6 100644 --- contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Parser.h +++ contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Parser.h @@ -280,4 +280,4 @@ private: } // namespace ast_matchers } // namespace clang -#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H +#endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H diff --git contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Registry.h contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Registry.h index f91f5fe01c4e..ee47469c6e18 100644 --- contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Registry.h +++ contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Registry.h @@ -157,4 +157,4 @@ public: } // namespace ast_matchers } // namespace clang -#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H +#endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H diff --git contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h index 5b3f8a7ca5eb..e1c19eb835ba 100644 --- contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h +++ contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h @@ -356,4 +356,4 @@ private: } // end namespace ast_matchers } // end namespace clang -#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H +#endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H diff --git contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h index a0c767bf92d2..6d78fa4a897a 100644 --- contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h +++ contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h @@ -20,7 +20,6 @@ class AnalysisDeclContext; class BlockDecl; class CFG; class Decl; -class DeclContext; class Expr; class ParmVarDecl; class Stmt; diff --git contrib/llvm-project/clang/include/clang/Analysis/Analyses/Consumed.h contrib/llvm-project/clang/include/clang/Analysis/Analyses/Consumed.h index dec1ae3b2b4b..24702567ab6c 100644 --- contrib/llvm-project/clang/include/clang/Analysis/Analyses/Consumed.h +++ contrib/llvm-project/clang/include/clang/Analysis/Analyses/Consumed.h @@ -153,8 +153,7 @@ namespace consumed { public: ConsumedStateMap() = default; ConsumedStateMap(const ConsumedStateMap &Other) - : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap), - TmpMap() {} + : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap) {} /// Warn if any of the parameters being tracked are not in the state /// they were declared to be in upon return from a function. diff --git contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index a0ae44131b45..2f6a78126a1d 100644 --- contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -517,4 +517,4 @@ void printSCFG(CFGWalker &Walker); } // namespace threadSafety } // namespace clang -#endif // LLVM_CLANG_THREAD_SAFETY_COMMON_H +#endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H diff --git contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h index e3b6e61d3026..088474b9b298 100644 --- contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h +++ contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h @@ -354,4 +354,4 @@ inline std::ostream& operator<<(std::ostream& ss, const StringRef str) { } // namespace threadSafety } // namespace clang -#endif // LLVM_CLANG_THREAD_SAFETY_UTIL_H +#endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYUTIL_H diff --git contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h index 846ff7719ce1..6e5e019ce263 100644 --- contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h +++ contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// // -#ifndef LLVM_CLANG_ANALYSIS_ANY_CALL_H -#define LLVM_CLANG_ANALYSIS_ANY_CALL_H +#ifndef LLVM_CLANG_ANALYSIS_ANYCALL_H +#define LLVM_CLANG_ANALYSIS_ANYCALL_H #include "clang/AST/Decl.h" #include "clang/AST/ExprCXX.h" @@ -215,4 +215,4 @@ public: } -#endif // LLVM_CLANG_ANALYSIS_ANY_CALL_H +#endif // LLVM_CLANG_ANALYSIS_ANYCALL_H diff --git contrib/llvm-project/clang/include/clang/Analysis/BodyFarm.h contrib/llvm-project/clang/include/clang/Analysis/BodyFarm.h index 72607f8839f5..d947ac070209 100644 --- contrib/llvm-project/clang/include/clang/Analysis/BodyFarm.h +++ contrib/llvm-project/clang/include/clang/Analysis/BodyFarm.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H -#define LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H +#ifndef LLVM_CLANG_ANALYSIS_BODYFARM_H +#define LLVM_CLANG_ANALYSIS_BODYFARM_H #include "clang/AST/DeclBase.h" #include "clang/Basic/LLVM.h" @@ -24,7 +24,6 @@ namespace clang { class ASTContext; class FunctionDecl; class ObjCMethodDecl; -class ObjCPropertyDecl; class Stmt; class CodeInjector; diff --git contrib/llvm-project/clang/include/clang/Analysis/CFG.h contrib/llvm-project/clang/include/clang/Analysis/CFG.h index b8e453fcc235..c5512a7e1499 100644 --- contrib/llvm-project/clang/include/clang/Analysis/CFG.h +++ contrib/llvm-project/clang/include/clang/Analysis/CFG.h @@ -707,7 +707,7 @@ class CFGBlock { template <bool IsOtherConst> ElementRefIterator(ElementRefIterator<true, IsOtherConst> E) - : ElementRefIterator(E.Parent, llvm::make_reverse_iterator(E.Pos)) {} + : ElementRefIterator(E.Parent, std::make_reverse_iterator(E.Pos)) {} bool operator<(ElementRefIterator Other) const { assert(Parent == Other.Parent); diff --git contrib/llvm-project/clang/include/clang/Analysis/CloneDetection.h contrib/llvm-project/clang/include/clang/Analysis/CloneDetection.h index 0b86c7fd86dd..b2911a5b44eb 100644 --- contrib/llvm-project/clang/include/clang/Analysis/CloneDetection.h +++ contrib/llvm-project/clang/include/clang/Analysis/CloneDetection.h @@ -11,8 +11,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_AST_CLONEDETECTION_H -#define LLVM_CLANG_AST_CLONEDETECTION_H +#ifndef LLVM_CLANG_ANALYSIS_CLONEDETECTION_H +#define LLVM_CLANG_ANALYSIS_CLONEDETECTION_H #include "clang/AST/StmtVisitor.h" #include "llvm/Support/Regex.h" @@ -441,4 +441,4 @@ struct MatchingVariablePatternConstraint { } // end namespace clang -#endif // LLVM_CLANG_AST_CLONEDETECTION_H +#endif // LLVM_CLANG_ANALYSIS_CLONEDETECTION_H diff --git contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h new file mode 100644 index 000000000000..e6ceb3a89131 --- /dev/null +++ contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h @@ -0,0 +1,57 @@ +//===-- ControlFlowContext.h ------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines a ControlFlowContext class that is used by dataflow +// analyses that run over Control-Flow Graphs (CFGs). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Stmt.h" +#include "clang/Analysis/CFG.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Error.h" +#include <memory> +#include <utility> + +namespace clang { +namespace dataflow { + +/// Holds CFG and other derived context that is needed to perform dataflow +/// analysis. +class ControlFlowContext { +public: + /// Builds a ControlFlowContext from an AST node. + static llvm::Expected<ControlFlowContext> build(const Decl *D, Stmt *S, + ASTContext *C); + + /// Returns the CFG that is stored in this context. + const CFG &getCFG() const { return *Cfg; } + + /// Returns a mapping from statements to basic blocks that contain them. + const llvm::DenseMap<const Stmt *, const CFGBlock *> &getStmtToBlock() const { + return StmtToBlock; + } + +private: + ControlFlowContext(std::unique_ptr<CFG> Cfg, + llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock) + : Cfg(std::move(Cfg)), StmtToBlock(std::move(StmtToBlock)) {} + + std::unique_ptr<CFG> Cfg; + llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock; +}; + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H diff --git contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h index a5d4a5d6ba40..f327abe63751 100644 --- contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -21,6 +21,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Stmt.h" #include "clang/Analysis/CFG.h" +#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h" #include "llvm/ADT/Any.h" @@ -38,9 +39,13 @@ namespace dataflow { /// must provide the following public members: /// * `LatticeT initialElement()` - returns a lattice element that models the /// initial state of a basic block; -/// * `LatticeT transfer(const Stmt *, const LatticeT &, Environment &)` - -/// applies the analysis transfer function for a given statement and lattice -/// element. +/// * `void transfer(const Stmt *, LatticeT &, Environment &)` - applies the +/// analysis transfer function for a given statement and lattice element. +/// +/// `Derived` can optionally override the following members: +/// * `bool merge(QualType, const Value &, const Value &, Value &, +/// Environment &)` - joins distinct values. This could be a strict +/// lattice join or a more general widening operation. /// /// `LatticeT` is a bounded join-semilattice that is used by `Derived` and must /// provide the following public members: @@ -57,6 +62,8 @@ public: using Lattice = LatticeT; explicit DataflowAnalysis(ASTContext &Context) : Context(Context) {} + explicit DataflowAnalysis(ASTContext &Context, bool ApplyBuiltinTransfer) + : TypeErasedDataflowAnalysis(ApplyBuiltinTransfer), Context(Context) {} ASTContext &getASTContext() final { return Context; } @@ -78,11 +85,10 @@ public: return L1 == L2; } - TypeErasedLattice transferTypeErased(const Stmt *Stmt, - const TypeErasedLattice &E, - Environment &Env) final { - const Lattice &L = llvm::any_cast<const Lattice &>(E.Value); - return {static_cast<Derived *>(this)->transfer(Stmt, L, Env)}; + void transferTypeErased(const Stmt *Stmt, TypeErasedLattice &E, + Environment &Env) final { + Lattice &L = llvm::any_cast<Lattice &>(E.Value); + static_cast<Derived *>(this)->transfer(Stmt, L, Env); } private: @@ -101,17 +107,12 @@ template <typename LatticeT> struct DataflowAnalysisState { /// Performs dataflow analysis and returns a mapping from basic block IDs to /// dataflow analysis states that model the respective basic blocks. Indices /// of the returned vector correspond to basic block IDs. -/// -/// Requirements: -/// -/// `Cfg` must have been built with `CFG::BuildOptions::setAllAlwaysAdd()` to -/// ensure that all sub-expressions in a basic block are evaluated. template <typename AnalysisT> std::vector<llvm::Optional<DataflowAnalysisState<typename AnalysisT::Lattice>>> -runDataflowAnalysis(const CFG &Cfg, AnalysisT &Analysis, +runDataflowAnalysis(const ControlFlowContext &CFCtx, AnalysisT &Analysis, const Environment &InitEnv) { auto TypeErasedBlockStates = - runTypeErasedDataflowAnalysis(Cfg, Analysis, InitEnv); + runTypeErasedDataflowAnalysis(CFCtx, Analysis, InitEnv); std::vector< llvm::Optional<DataflowAnalysisState<typename AnalysisT::Lattice>>> BlockStates; diff --git contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h new file mode 100644 index 000000000000..5c1b41d53892 --- /dev/null +++ contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h @@ -0,0 +1,145 @@ +//===-- DataflowAnalysisContext.h -------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines a DataflowAnalysisContext class that owns objects that +// encompass the state of a program and stores context that is used during +// dataflow analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSISCONTEXT_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSISCONTEXT_H + +#include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" +#include "clang/Analysis/FlowSensitive/StorageLocation.h" +#include "clang/Analysis/FlowSensitive/Value.h" +#include "llvm/ADT/DenseMap.h" +#include <cassert> +#include <memory> +#include <type_traits> +#include <utility> +#include <vector> + +namespace clang { +namespace dataflow { + +/// Owns objects that encompass the state of a program and stores context that +/// is used during dataflow analysis. +class DataflowAnalysisContext { +public: + DataflowAnalysisContext() + : TrueVal(&takeOwnership(std::make_unique<BoolValue>())), + FalseVal(&takeOwnership(std::make_unique<BoolValue>())) {} + + /// Takes ownership of `Loc` and returns a reference to it. + /// + /// Requirements: + /// + /// `Loc` must not be null. + template <typename T> + typename std::enable_if<std::is_base_of<StorageLocation, T>::value, T &>::type + takeOwnership(std::unique_ptr<T> Loc) { + assert(Loc != nullptr); + Locs.push_back(std::move(Loc)); + return *cast<T>(Locs.back().get()); + } + + /// Takes ownership of `Val` and returns a reference to it. + /// + /// Requirements: + /// + /// `Val` must not be null. + template <typename T> + typename std::enable_if<std::is_base_of<Value, T>::value, T &>::type + takeOwnership(std::unique_ptr<T> Val) { + assert(Val != nullptr); + Vals.push_back(std::move(Val)); + return *cast<T>(Vals.back().get()); + } + + /// Assigns `Loc` as the storage location of `D`. + /// + /// Requirements: + /// + /// `D` must not be assigned a storage location. + void setStorageLocation(const ValueDecl &D, StorageLocation &Loc) { + assert(DeclToLoc.find(&D) == DeclToLoc.end()); + DeclToLoc[&D] = &Loc; + } + + /// Returns the storage location assigned to `D` or null if `D` has no + /// assigned storage location. + StorageLocation *getStorageLocation(const ValueDecl &D) const { + auto It = DeclToLoc.find(&D); + return It == DeclToLoc.end() ? nullptr : It->second; + } + + /// Assigns `Loc` as the storage location of `E`. + /// + /// Requirements: + /// + /// `E` must not be assigned a storage location. + void setStorageLocation(const Expr &E, StorageLocation &Loc) { + assert(ExprToLoc.find(&E) == ExprToLoc.end()); + ExprToLoc[&E] = &Loc; + } + + /// Returns the storage location assigned to `E` or null if `E` has no + /// assigned storage location. + StorageLocation *getStorageLocation(const Expr &E) const { + auto It = ExprToLoc.find(&E); + return It == ExprToLoc.end() ? nullptr : It->second; + } + + /// Assigns `Loc` as the storage location of the `this` pointee. + /// + /// Requirements: + /// + /// The `this` pointee must not be assigned a storage location. + void setThisPointeeStorageLocation(StorageLocation &Loc) { + assert(ThisPointeeLoc == nullptr); + ThisPointeeLoc = &Loc; + } + + /// Returns the storage location assigned to the `this` pointee or null if the + /// `this` pointee has no assigned storage location. + StorageLocation *getThisPointeeStorageLocation() const { + return ThisPointeeLoc; + } + + /// Returns a symbolic boolean value that models a boolean literal equal to + /// `Value`. + BoolValue &getBoolLiteralValue(bool Value) const { + return Value ? *TrueVal : *FalseVal; + } + +private: + // Storage for the state of a program. + std::vector<std::unique_ptr<StorageLocation>> Locs; + std::vector<std::unique_ptr<Value>> Vals; + + // Maps from program declarations and statements to storage locations that are + // assigned to them. These assignments are global (aggregated across all basic + // blocks) and are used to produce stable storage locations when the same + // basic blocks are evaluated multiple times. The storage locations that are + // in scope for a particular basic block are stored in `Environment`. + llvm::DenseMap<const ValueDecl *, StorageLocation *> DeclToLoc; + llvm::DenseMap<const Expr *, StorageLocation *> ExprToLoc; + + StorageLocation *ThisPointeeLoc = nullptr; + + // FIXME: Add support for boolean expressions. + BoolValue *TrueVal; + BoolValue *FalseVal; +}; + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSISCONTEXT_H diff --git contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index 4a3c0239f8e1..e560305cf5ca 100644 --- contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -15,19 +15,215 @@ #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/Expr.h" +#include "clang/AST/Type.h" +#include "clang/AST/TypeOrdering.h" +#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowLattice.h" +#include "clang/Analysis/FlowSensitive/StorageLocation.h" +#include "clang/Analysis/FlowSensitive/Value.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include <memory> +#include <type_traits> +#include <utility> namespace clang { namespace dataflow { +/// Indicates what kind of indirections should be skipped past when retrieving +/// storage locations or values. +/// +/// FIXME: Consider renaming this or replacing it with a more appropriate model. +/// See the discussion in https://reviews.llvm.org/D116596 for context. +enum class SkipPast { + /// No indirections should be skipped past. + None, + /// An optional reference should be skipped past. + Reference, + /// An optional reference should be skipped past, then an optional pointer + /// should be skipped past. + ReferenceThenPointer, +}; + /// Holds the state of the program (store and heap) at a given program point. class Environment { public: - bool operator==(const Environment &) const { return true; } + /// Supplements `Environment` with non-standard join operations. + class Merger { + public: + virtual ~Merger() = default; + + /// Given distinct `Val1` and `Val2`, modifies `MergedVal` to approximate + /// both `Val1` and `Val2`. This could be a strict lattice join or a more + /// general widening operation. If this function returns true, `MergedVal` + /// will be assigned to a storage location of type `Type` in `Env`. + /// + /// Requirements: + /// + /// `Val1` and `Val2` must be distinct. + virtual bool merge(QualType Type, const Value &Val1, const Value &Val2, + Value &MergedVal, Environment &Env) { + return false; + } + }; + + /// Creates an environment that uses `DACtx` to store objects that encompass + /// the state of a program. + explicit Environment(DataflowAnalysisContext &DACtx) : DACtx(&DACtx) {} + + /// Creates an environment that uses `DACtx` to store objects that encompass + /// the state of a program. + /// + /// If `DeclCtx` is a function, initializes the environment with symbolic + /// representations of the function parameters. + /// + /// If `DeclCtx` is a non-static member function, initializes the environment + /// with a symbolic representation of the `this` pointee. + Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx); + + bool operator==(const Environment &) const; + + LatticeJoinEffect join(const Environment &, Environment::Merger &); + + // FIXME: Rename `createOrGetStorageLocation` to `getOrCreateStorageLocation`, + // `getStableStorageLocation`, or something more appropriate. + + /// Creates a storage location appropriate for `Type`. Does not assign a value + /// to the returned storage location in the environment. + /// + /// Requirements: + /// + /// `Type` must not be null. + StorageLocation &createStorageLocation(QualType Type); + + /// Creates a storage location for `D`. Does not assign the returned storage + /// location to `D` in the environment. Does not assign a value to the + /// returned storage location in the environment. + StorageLocation &createStorageLocation(const VarDecl &D); + + /// Creates a storage location for `E`. Does not assign the returned storage + /// location to `E` in the environment. Does not assign a value to the + /// returned storage location in the environment. + StorageLocation &createStorageLocation(const Expr &E); + + /// Assigns `Loc` as the storage location of `D` in the environment. + /// + /// Requirements: + /// + /// `D` must not be assigned a storage location in the environment. + void setStorageLocation(const ValueDecl &D, StorageLocation &Loc); + + /// Returns the storage location assigned to `D` in the environment, applying + /// the `SP` policy for skipping past indirections, or null if `D` isn't + /// assigned a storage location in the environment. + StorageLocation *getStorageLocation(const ValueDecl &D, SkipPast SP) const; + + /// Assigns `Loc` as the storage location of `E` in the environment. + /// + /// Requirements: + /// + /// `E` must not be assigned a storage location in the environment. + void setStorageLocation(const Expr &E, StorageLocation &Loc); + + /// Returns the storage location assigned to `E` in the environment, applying + /// the `SP` policy for skipping past indirections, or null if `E` isn't + /// assigned a storage location in the environment. + StorageLocation *getStorageLocation(const Expr &E, SkipPast SP) const; + + /// Returns the storage location assigned to the `this` pointee in the + /// environment or null if the `this` pointee has no assigned storage location + /// in the environment. + StorageLocation *getThisPointeeStorageLocation() const; - LatticeJoinEffect join(const Environment &) { - return LatticeJoinEffect::Unchanged; + /// Creates a value appropriate for `Type`, if `Type` is supported, otherwise + /// return null. If `Type` is a pointer or reference type, creates all the + /// necessary storage locations and values for indirections until it finds a + /// non-pointer/non-reference type. + /// + /// Requirements: + /// + /// `Type` must not be null. + Value *createValue(QualType Type); + + /// Assigns `Val` as the value of `Loc` in the environment. + void setValue(const StorageLocation &Loc, Value &Val); + + /// Returns the value assigned to `Loc` in the environment or null if `Loc` + /// isn't assigned a value in the environment. + Value *getValue(const StorageLocation &Loc) const; + + /// Equivalent to `getValue(getStorageLocation(D, SP), SkipPast::None)` if `D` + /// is assigned a storage location in the environment, otherwise returns null. + Value *getValue(const ValueDecl &D, SkipPast SP) const; + + /// Equivalent to `getValue(getStorageLocation(E, SP), SkipPast::None)` if `E` + /// is assigned a storage location in the environment, otherwise returns null. + Value *getValue(const Expr &E, SkipPast SP) const; + + /// Transfers ownership of `Loc` to the analysis context and returns a + /// reference to it. + /// + /// Requirements: + /// + /// `Loc` must not be null. + template <typename T> + typename std::enable_if<std::is_base_of<StorageLocation, T>::value, T &>::type + takeOwnership(std::unique_ptr<T> Loc) { + return DACtx->takeOwnership(std::move(Loc)); + } + + /// Transfers ownership of `Val` to the analysis context and returns a + /// reference to it. + /// + /// Requirements: + /// + /// `Val` must not be null. + template <typename T> + typename std::enable_if<std::is_base_of<Value, T>::value, T &>::type + takeOwnership(std::unique_ptr<T> Val) { + return DACtx->takeOwnership(std::move(Val)); } + + /// Returns a symbolic boolean value that models a boolean literal equal to + /// `Value` + BoolValue &getBoolLiteralValue(bool Value) const { + return DACtx->getBoolLiteralValue(Value); + } + +private: + /// Creates a value appropriate for `Type`, if `Type` is supported, otherwise + /// return null. + /// + /// Recursively initializes storage locations and values until it sees a + /// self-referential pointer or reference type. `Visited` is used to track + /// which types appeared in the reference/pointer chain in order to avoid + /// creating a cyclic dependency with self-referential pointers/references. + /// + /// Requirements: + /// + /// `Type` must not be null. + Value *createValueUnlessSelfReferential(QualType Type, + llvm::DenseSet<QualType> &Visited); + + StorageLocation &skip(StorageLocation &Loc, SkipPast SP) const; + const StorageLocation &skip(const StorageLocation &Loc, SkipPast SP) const; + + // `DACtx` is not null and not owned by this object. + DataflowAnalysisContext *DACtx; + + // Maps from program declarations and statements to storage locations that are + // assigned to them. Unlike the maps in `DataflowAnalysisContext`, these + // include only storage locations that are in scope for a particular basic + // block. + llvm::DenseMap<const ValueDecl *, StorageLocation *> DeclToLoc; + llvm::DenseMap<const Expr *, StorageLocation *> ExprToLoc; + + llvm::DenseMap<const StorageLocation *, Value *> LocToVal; + + // FIXME: Add flow condition constraints. }; } // namespace dataflow diff --git contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h index 52d84eb13c56..e926adf6f0b2 100644 --- contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h +++ contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h @@ -92,4 +92,4 @@ struct BackwardDataflowWorklist } // namespace clang -#endif // LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWWORKLIST_H diff --git contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/MapLattice.h contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/MapLattice.h new file mode 100644 index 000000000000..ff403f68b7c5 --- /dev/null +++ contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/MapLattice.h @@ -0,0 +1,140 @@ +//===------------------------ MapLattice.h ----------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines a parameterized lattice that maps keys to individual +// lattice elements (of the parameter lattice type). A typical usage is lifting +// a particular lattice to all variables in a lexical scope. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE__MAPLATTICE_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE__MAPLATTICE_H + +#include <ostream> +#include <string> +#include <utility> + +#include "DataflowAnalysis.h" +#include "clang/AST/Decl.h" +#include "clang/Analysis/FlowSensitive/DataflowLattice.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { +namespace dataflow { + +/// A lattice that maps keys to individual lattice elements. When instantiated +/// with an `ElementLattice` that is a bounded semi-lattice, `MapLattice` is +/// itself a bounded semi-lattice, so long as the user limits themselves to a +/// finite number of keys. In that case, `top` is (implicitly), the map +/// containing all valid keys mapped to `top` of `ElementLattice`. +/// +/// Requirements on `ElementLattice`: +/// * Provides standard declarations of a bounded semi-lattice. +template <typename Key, typename ElementLattice> class MapLattice { + using Container = llvm::DenseMap<Key, ElementLattice>; + Container C; + +public: + using key_type = Key; + using mapped_type = ElementLattice; + using value_type = typename Container::value_type; + using iterator = typename Container::iterator; + using const_iterator = typename Container::const_iterator; + + MapLattice() = default; + + explicit MapLattice(Container C) { C = std::move(C); } + + // The `bottom` element is the empty map. + static MapLattice bottom() { return MapLattice(); } + + void insert(const std::pair<const key_type, mapped_type> &P) { C.insert(P); } + + void insert(std::pair<const key_type, mapped_type> &&P) { + C.insert(std::move(P)); + } + + unsigned size() const { return C.size(); } + bool empty() const { return C.empty(); } + + iterator begin() { return C.begin(); } + iterator end() { return C.end(); } + const_iterator begin() const { return C.begin(); } + const_iterator end() const { return C.end(); } + + // Equality is direct equality of underlying map entries. One implication of + // this definition is that a map with (only) keys that map to bottom is not + // equal to the empty map. + friend bool operator==(const MapLattice &LHS, const MapLattice &RHS) { + return LHS.C == RHS.C; + } + + friend bool operator!=(const MapLattice &LHS, const MapLattice &RHS) { + return !(LHS == RHS); + } + + bool contains(const key_type &K) const { return C.find(K) != C.end(); } + + iterator find(const key_type &K) { return C.find(K); } + const_iterator find(const key_type &K) const { return C.find(K); } + + mapped_type &operator[](const key_type &K) { return C[K]; } + + /// If an entry exists in one map but not the other, the missing entry is + /// treated as implicitly mapping to `bottom`. So, the joined map contains the + /// entry as it was in the source map. + LatticeJoinEffect join(const MapLattice &Other) { + LatticeJoinEffect Effect = LatticeJoinEffect::Unchanged; + for (const auto &O : Other.C) { + auto It = C.find(O.first); + if (It == C.end()) { + C.insert(O); + Effect = LatticeJoinEffect::Changed; + } else if (It->second.join(O.second) == LatticeJoinEffect::Changed) + Effect = LatticeJoinEffect::Changed; + } + return Effect; + } +}; + +/// Convenience alias that captures the common use of map lattices to model +/// in-scope variables. +template <typename ElementLattice> +using VarMapLattice = MapLattice<const clang::VarDecl *, ElementLattice>; + +template <typename Key, typename ElementLattice> +std::ostream & +operator<<(std::ostream &Os, + const clang::dataflow::MapLattice<Key, ElementLattice> &M) { + std::string Separator = ""; + Os << "{"; + for (const auto &E : M) { + Os << std::exchange(Separator, ", ") << E.first << " => " << E.second; + } + Os << "}"; + return Os; +} + +template <typename ElementLattice> +std::ostream & +operator<<(std::ostream &Os, + const clang::dataflow::VarMapLattice<ElementLattice> &M) { + std::string Separator = ""; + Os << "{"; + for (const auto &E : M) { + Os << std::exchange(Separator, ", ") << E.first->getName().str() << " => " + << E.second; + } + Os << "}"; + return Os; +} +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE__MAPLATTICE_H diff --git contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h new file mode 100644 index 000000000000..5532813d6d29 --- /dev/null +++ contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h @@ -0,0 +1,89 @@ +//===-- StorageLocation.h ---------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines classes that represent elements of the local variable store +// and of the heap during dataflow analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H + +#include "clang/AST/Decl.h" +#include "clang/AST/Type.h" +#include "llvm/ADT/DenseMap.h" + +namespace clang { +namespace dataflow { + +/// Base class for elements of the local variable store and of the heap. +/// +/// Each storage location holds a value. The mapping from storage locations to +/// values is stored in the environment. +class StorageLocation { +public: + enum class Kind { Scalar, Aggregate }; + + StorageLocation(Kind LocKind, QualType Type) : LocKind(LocKind), Type(Type) {} + + virtual ~StorageLocation() = default; + + Kind getKind() const { return LocKind; } + + QualType getType() const { return Type; } + +private: + Kind LocKind; + QualType Type; +}; + +/// A storage location that is not subdivided further for the purposes of +/// abstract interpretation. For example: `int`, `int*`, `int&`. +class ScalarStorageLocation final : public StorageLocation { +public: + explicit ScalarStorageLocation(QualType Type) + : StorageLocation(Kind::Scalar, Type) {} + + static bool classof(const StorageLocation *Loc) { + return Loc->getKind() == Kind::Scalar; + } +}; + +/// A storage location which is subdivided into smaller storage locations that +/// can be traced independently by abstract interpretation. For example: a +/// struct with public members. +class AggregateStorageLocation final : public StorageLocation { +public: + explicit AggregateStorageLocation(QualType Type) + : AggregateStorageLocation( + Type, llvm::DenseMap<const ValueDecl *, StorageLocation *>()) {} + + AggregateStorageLocation( + QualType Type, + llvm::DenseMap<const ValueDecl *, StorageLocation *> Children) + : StorageLocation(Kind::Aggregate, Type), Children(std::move(Children)) {} + + static bool classof(const StorageLocation *Loc) { + return Loc->getKind() == Kind::Aggregate; + } + + /// Returns the child storage location for `D`. + StorageLocation &getChild(const ValueDecl &D) const { + auto It = Children.find(&D); + assert(It != Children.end()); + return *It->second; + } + +private: + llvm::DenseMap<const ValueDecl *, StorageLocation *> Children; +}; + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H diff --git contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h new file mode 100644 index 000000000000..a12674a173be --- /dev/null +++ contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h @@ -0,0 +1,33 @@ +//===-- Transfer.h ----------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines a transfer function that evaluates a program statement and +// updates an environment accordingly. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TRANSFER_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TRANSFER_H + +#include "clang/AST/Stmt.h" +#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" + +namespace clang { +namespace dataflow { + +/// Evaluates `S` and updates `Env` accordingly. +/// +/// Requirements: +/// +/// The type of `S` must not be `ParenExpr`. +void transfer(const Stmt &S, Environment &Env); + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TRANSFER_H diff --git contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h index 6193b9860d33..9f44475b14ba 100644 --- contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h +++ contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h @@ -14,11 +14,13 @@ #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H +#include <utility> #include <vector> #include "clang/AST/ASTContext.h" #include "clang/AST/Stmt.h" #include "clang/Analysis/CFG.h" +#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/DataflowLattice.h" #include "llvm/ADT/Any.h" @@ -38,8 +40,18 @@ struct TypeErasedLattice { }; /// Type-erased base class for dataflow analyses built on a single lattice type. -class TypeErasedDataflowAnalysis { +class TypeErasedDataflowAnalysis : public Environment::Merger { + /// Determines whether to apply the built-in transfer functions. + // FIXME: Remove this option once the framework supports composing analyses + // (at which point the built-in transfer functions can be simply a standalone + // analysis). + bool ApplyBuiltinTransfer; + public: + TypeErasedDataflowAnalysis() : ApplyBuiltinTransfer(true) {} + TypeErasedDataflowAnalysis(bool ApplyBuiltinTransfer) + : ApplyBuiltinTransfer(ApplyBuiltinTransfer) {} + virtual ~TypeErasedDataflowAnalysis() {} /// Returns the `ASTContext` that is used by the analysis. @@ -62,9 +74,12 @@ public: /// Applies the analysis transfer function for a given statement and /// type-erased lattice element. - virtual TypeErasedLattice transferTypeErased(const Stmt *, - const TypeErasedLattice &, - Environment &) = 0; + virtual void transferTypeErased(const Stmt *, TypeErasedLattice &, + Environment &) = 0; + + /// Determines whether to apply the built-in transfer functions, which model + /// the heap and stack in the `Environment`. + bool applyBuiltinTransfer() const { return ApplyBuiltinTransfer; } }; /// Type-erased model of the program at a given program point. @@ -74,6 +89,9 @@ struct TypeErasedDataflowAnalysisState { /// Model of the state of the program (store and heap). Environment Env; + + TypeErasedDataflowAnalysisState(TypeErasedLattice Lattice, Environment Env) + : Lattice(std::move(Lattice)), Env(std::move(Env)) {} }; /// Transfers the state of a basic block by evaluating each of its statements in @@ -87,6 +105,7 @@ struct TypeErasedDataflowAnalysisState { /// already been transferred. States in `BlockStates` that are set to /// `llvm::None` represent basic blocks that are not evaluated yet. TypeErasedDataflowAnalysisState transferBlock( + const ControlFlowContext &CFCtx, std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> &BlockStates, const CFGBlock &Block, const Environment &InitEnv, TypeErasedDataflowAnalysis &Analysis, @@ -97,13 +116,8 @@ TypeErasedDataflowAnalysisState transferBlock( /// Performs dataflow analysis and returns a mapping from basic block IDs to /// dataflow analysis states that model the respective basic blocks. Indices /// of the returned vector correspond to basic block IDs. -/// -/// Requirements: -/// -/// `Cfg` must have been built with `CFG::BuildOptions::setAllAlwaysAdd()` to -/// ensure that all sub-expressions in a basic block are evaluated. std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> -runTypeErasedDataflowAnalysis(const CFG &Cfg, +runTypeErasedDataflowAnalysis(const ControlFlowContext &CFCtx, TypeErasedDataflowAnalysis &Analysis, const Environment &InitEnv); diff --git contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h new file mode 100644 index 000000000000..da04f926c597 --- /dev/null +++ contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h @@ -0,0 +1,144 @@ +//===-- Value.h -------------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for values computed by abstract interpretation +// during dataflow analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H + +#include "clang/AST/Decl.h" +#include "clang/Analysis/FlowSensitive/StorageLocation.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include <cassert> +#include <utility> + +namespace clang { +namespace dataflow { + +/// Base class for all values computed by abstract interpretation. +class Value { +public: + enum class Kind { Bool, Integer, Reference, Pointer, Struct }; + + explicit Value(Kind ValKind) : ValKind(ValKind) {} + + virtual ~Value() = default; + + Kind getKind() const { return ValKind; } + +private: + Kind ValKind; +}; + +/// Models a boolean. +class BoolValue : public Value { +public: + explicit BoolValue() : Value(Kind::Bool) {} + + static bool classof(const Value *Val) { return Val->getKind() == Kind::Bool; } +}; + +/// Models an integer. +class IntegerValue : public Value { +public: + explicit IntegerValue() : Value(Kind::Integer) {} + + static bool classof(const Value *Val) { + return Val->getKind() == Kind::Integer; + } +}; + +/// Base class for values that refer to storage locations. +class IndirectionValue : public Value { +public: + /// Constructs a value that refers to `PointeeLoc`. + explicit IndirectionValue(Kind ValueKind, StorageLocation &PointeeLoc) + : Value(ValueKind), PointeeLoc(PointeeLoc) {} + + static bool classof(const Value *Val) { + return Val->getKind() == Kind::Reference || Val->getKind() == Kind::Pointer; + } + + StorageLocation &getPointeeLoc() const { return PointeeLoc; } + +private: + StorageLocation &PointeeLoc; +}; + +/// Models a dereferenced pointer. For example, a reference in C++ or an lvalue +/// in C. +class ReferenceValue final : public IndirectionValue { +public: + explicit ReferenceValue(StorageLocation &PointeeLoc) + : IndirectionValue(Kind::Reference, PointeeLoc) {} + + static bool classof(const Value *Val) { + return Val->getKind() == Kind::Reference; + } +}; + +/// Models a symbolic pointer. Specifically, any value of type `T*`. +class PointerValue final : public IndirectionValue { +public: + explicit PointerValue(StorageLocation &PointeeLoc) + : IndirectionValue(Kind::Pointer, PointeeLoc) {} + + static bool classof(const Value *Val) { + return Val->getKind() == Kind::Pointer; + } +}; + +/// Models a value of `struct` or `class` type. +class StructValue final : public Value { +public: + StructValue() : StructValue(llvm::DenseMap<const ValueDecl *, Value *>()) {} + + explicit StructValue(llvm::DenseMap<const ValueDecl *, Value *> Children) + : Value(Kind::Struct), Children(std::move(Children)) {} + + static bool classof(const Value *Val) { + return Val->getKind() == Kind::Struct; + } + + /// Returns the child value that is assigned for `D`. + Value &getChild(const ValueDecl &D) const { + auto It = Children.find(&D); + assert(It != Children.end()); + return *It->second; + } + + /// Assigns `Val` as the child value for `D`. + void setChild(const ValueDecl &D, Value &Val) { Children[&D] = &Val; } + + /// Returns the value of the synthetic property with the given `Name` or null + /// if the property isn't assigned a value. + Value *getProperty(llvm::StringRef Name) const { + auto It = Properties.find(Name); + return It == Properties.end() ? nullptr : It->second; + } + + /// Assigns `Val` as the value of the synthetic property with the given + /// `Name`. + void setProperty(llvm::StringRef Name, Value &Val) { + Properties.insert_or_assign(Name, &Val); + } + +private: + llvm::DenseMap<const ValueDecl *, Value *> Children; + llvm::StringMap<Value *> Properties; +}; + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H diff --git contrib/llvm-project/clang/include/clang/Analysis/IssueHash.h contrib/llvm-project/clang/include/clang/Analysis/IssueHash.h index 9c02b79f58f9..78bebbdb6ec7 100644 --- contrib/llvm-project/clang/include/clang/Analysis/IssueHash.h +++ contrib/llvm-project/clang/include/clang/Analysis/IssueHash.h @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_STATICANALYZER_CORE_ISSUE_HASH_H -#define LLVM_CLANG_STATICANALYZER_CORE_ISSUE_HASH_H +#ifndef LLVM_CLANG_ANALYSIS_ISSUEHASH_H +#define LLVM_CLANG_ANALYSIS_ISSUEHASH_H #include "llvm/ADT/SmallString.h" diff --git contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h index 235d26083191..446f67b23e75 100644 --- contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h +++ contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H -#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H +#ifndef LLVM_CLANG_ANALYSIS_PATHDIAGNOSTIC_H +#define LLVM_CLANG_ANALYSIS_PATHDIAGNOSTIC_H #include "clang/AST/Stmt.h" #include "clang/Analysis/AnalysisDeclContext.h" @@ -41,10 +41,8 @@ class AnalysisDeclContext; class BinaryOperator; class CallEnter; class CallExitEnd; -class CallExpr; class ConditionalOperator; class Decl; -class Expr; class LocationContext; class MemberExpr; class ProgramPoint; @@ -905,4 +903,4 @@ public: } // namespace ento } // namespace clang -#endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H +#endif // LLVM_CLANG_ANALYSIS_PATHDIAGNOSTIC_H diff --git contrib/llvm-project/clang/include/clang/Analysis/ProgramPoint.h contrib/llvm-project/clang/include/clang/Analysis/ProgramPoint.h index 546224bfd58d..680713a52f2f 100644 --- contrib/llvm-project/clang/include/clang/Analysis/ProgramPoint.h +++ contrib/llvm-project/clang/include/clang/Analysis/ProgramPoint.h @@ -30,7 +30,6 @@ namespace clang { class AnalysisDeclContext; -class FunctionDecl; class LocationContext; /// ProgramPoints can be "tagged" as representing points specific to a given diff --git contrib/llvm-project/clang/include/clang/Analysis/RetainSummaryManager.h contrib/llvm-project/clang/include/clang/Analysis/RetainSummaryManager.h index b7ccb0317830..d9a0416e1ce5 100644 --- contrib/llvm-project/clang/include/clang/Analysis/RetainSummaryManager.h +++ contrib/llvm-project/clang/include/clang/Analysis/RetainSummaryManager.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H -#define LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H +#ifndef LLVM_CLANG_ANALYSIS_RETAINSUMMARYMANAGER_H +#define LLVM_CLANG_ANALYSIS_RETAINSUMMARYMANAGER_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" diff --git contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h index d26e9159a937..278f20e87cc6 100644 --- contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h +++ contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LIB_ANALYSIS_SELECTOREXTRAS_H -#define LLVM_CLANG_LIB_ANALYSIS_SELECTOREXTRAS_H +#ifndef LLVM_CLANG_ANALYSIS_SELECTOREXTRAS_H +#define LLVM_CLANG_ANALYSIS_SELECTOREXTRAS_H #include "clang/AST/ASTContext.h" diff --git contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h index ab9f19da5d59..c1187b81420b 100644 --- contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h +++ contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h @@ -12,8 +12,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H -#define LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H +#ifndef LLVM_CLANG_BASIC_ALIGNEDALLOCATION_H +#define LLVM_CLANG_BASIC_ALIGNEDALLOCATION_H #include "llvm/ADT/Triple.h" #include "llvm/Support/ErrorHandling.h" @@ -42,4 +42,4 @@ inline llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) { } // end namespace clang -#endif // LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H +#endif // LLVM_CLANG_BASIC_ALIGNEDALLOCATION_H diff --git contrib/llvm-project/clang/include/clang/Basic/Attr.td contrib/llvm-project/clang/include/clang/Basic/Attr.td index 10c5c7f1b879..be56373cc3ca 100644 --- contrib/llvm-project/clang/include/clang/Basic/Attr.td +++ contrib/llvm-project/clang/include/clang/Basic/Attr.td @@ -1191,6 +1191,13 @@ def SYCLKernel : InheritableAttr { let Documentation = [SYCLKernelDocs]; } +def SYCLSpecialClass: InheritableAttr { + let Spellings = [Clang<"sycl_special_class">]; + let Subjects = SubjectList<[CXXRecord]>; + let LangOpts = [SYCL]; + let Documentation = [SYCLSpecialClassDocs]; +} + def C11NoReturn : InheritableAttr { let Spellings = [Keyword<"_Noreturn">]; let Subjects = SubjectList<[Function], ErrorDiag>; @@ -3686,6 +3693,8 @@ def OMPDeclareTargetDecl : InheritableAttr { EnumArgument<"DevType", "DevTypeTy", [ "host", "nohost", "any" ], [ "DT_Host", "DT_NoHost", "DT_Any" ]>, + ExprArgument<"IndirectExpr">, + BoolArgument<"Indirect">, UnsignedArgument<"Level"> ]; let AdditionalMembers = [{ diff --git contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td index 8a7424a88c9f..18fac924b114 100644 --- contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td +++ contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td @@ -409,6 +409,71 @@ The SYCL kernel in the previous code sample meets these expectations. }]; } +def SYCLSpecialClassDocs : Documentation { + let Category = DocCatStmt; + let Content = [{ +SYCL defines some special classes (accessor, sampler, and stream) which require +specific handling during the generation of the SPIR entry point. +The ``__attribute__((sycl_special_class))`` attribute is used in SYCL +headers to indicate that a class or a struct needs a specific handling when +it is passed from host to device. +Special classes will have a mandatory ``__init`` method and an optional +``__finalize`` method (the ``__finalize`` method is used only with the +``stream`` type). Kernel parameters types are extract from the ``__init`` method +parameters. The kernel function arguments list is derived from the +arguments of the ``__init`` method. The arguments of the ``__init`` method are +copied into the kernel function argument list and the ``__init`` and +``__finalize`` methods are called at the beginning and the end of the kernel, +respectively. +The ``__init`` and ``__finalize`` methods must be defined inside the +special class. +Please note that this is an attribute that is used as an internal +implementation detail and not intended to be used by external users. + +The syntax of the attribute is as follows: + +.. code-block:: c++ + + class __attribute__((sycl_special_class)) accessor {}; + class [[clang::sycl_special_class]] accessor {}; + +This is a code example that illustrates the use of the attribute: + +.. code-block:: c++ + + class __attribute__((sycl_special_class)) SpecialType { + int F1; + int F2; + void __init(int f1) { + F1 = f1; + F2 = f1; + } + void __finalize() {} + public: + SpecialType() = default; + int getF2() const { return F2; } + }; + + int main () { + SpecialType T; + cgh.single_task([=] { + T.getF2(); + }); +} + +This would trigger the following kernel entry point in the AST: + +.. code-block:: c++ + + void __sycl_kernel(int f1) { + SpecialType T; + T.__init(f1); + ... + T.__finalize() + } + }]; +} + def C11NoReturnDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -5987,7 +6052,7 @@ attribute requires a string literal argument to identify the handle being releas def DiagnoseAsBuiltinDocs : Documentation { let Category = DocCatFunction; let Content = [{ -The ``diagnose_as_builtin` attribute indicates that Fortify diagnostics are to +The ``diagnose_as_builtin`` attribute indicates that Fortify diagnostics are to be applied to the declared function as if it were the function specified by the attribute. The builtin function whose diagnostics are to be mimicked should be given. In addition, the order in which arguments should be applied must also @@ -5995,12 +6060,12 @@ be given. For example, the attribute can be used as follows. - .. code-block:: c +.. code-block:: c - __attribute__((diagnose_as_builtin(__builtin_memset, 3, 2, 1))) - void *mymemset(int n, int c, void *s) { - // ... - } + __attribute__((diagnose_as_builtin(__builtin_memset, 3, 2, 1))) + void *mymemset(int n, int c, void *s) { + // ... + } This indicates that calls to ``mymemset`` should be diagnosed as if they were calls to ``__builtin_memset``. The arguments ``3, 2, 1`` indicate by index the @@ -6015,7 +6080,8 @@ they would to the builtin function, after all normal arguments. For instance, to diagnose a new function as if it were `sscanf`, we can use the attribute as follows. - .. code-block:: c +.. code-block:: c + __attribute__((diagnose_as_builtin(sscanf, 1, 2))) int mysscanf(const char *str, const char *format, ...) { // ... diff --git contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h index 010cefcaf340..4a4c1a883cf4 100644 --- contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h +++ contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_BASIC_ATTR_SUBJECT_MATCH_RULES_H -#define LLVM_CLANG_BASIC_ATTR_SUBJECT_MATCH_RULES_H +#ifndef LLVM_CLANG_BASIC_ATTRSUBJECTMATCHRULES_H +#define LLVM_CLANG_BASIC_ATTRSUBJECTMATCHRULES_H #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/DenseMap.h" diff --git contrib/llvm-project/clang/include/clang/Basic/Builtins.def contrib/llvm-project/clang/include/clang/Basic/Builtins.def index 45d445163749..d2cb14d2fd8c 100644 --- contrib/llvm-project/clang/include/clang/Basic/Builtins.def +++ contrib/llvm-project/clang/include/clang/Basic/Builtins.def @@ -26,6 +26,7 @@ // i -> int // h -> half (__fp16, OpenCL) // x -> half (_Float16) +// y -> half (__bf16) // f -> float // d -> double // z -> size_t @@ -640,16 +641,23 @@ BUILTIN(__builtin_unreachable, "v", "nr") BUILTIN(__builtin_shufflevector, "v." , "nct") BUILTIN(__builtin_convertvector, "v." , "nct") BUILTIN(__builtin_alloca, "v*z" , "Fn") +BUILTIN(__builtin_alloca_uninitialized, "v*z", "Fn") BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn") +BUILTIN(__builtin_alloca_with_align_uninitialized, "v*zIz", "Fn") BUILTIN(__builtin_call_with_static_chain, "v.", "nt") BUILTIN(__builtin_elementwise_abs, "v.", "nct") BUILTIN(__builtin_elementwise_max, "v.", "nct") BUILTIN(__builtin_elementwise_min, "v.", "nct") BUILTIN(__builtin_elementwise_ceil, "v.", "nct") +BUILTIN(__builtin_elementwise_floor, "v.", "nct") +BUILTIN(__builtin_elementwise_roundeven, "v.", "nct") +BUILTIN(__builtin_elementwise_trunc, "v.", "nct") BUILTIN(__builtin_reduce_max, "v.", "nct") BUILTIN(__builtin_reduce_min, "v.", "nct") BUILTIN(__builtin_reduce_xor, "v.", "nct") +BUILTIN(__builtin_reduce_or, "v.", "nct") +BUILTIN(__builtin_reduce_and, "v.", "nct") BUILTIN(__builtin_matrix_transpose, "v.", "nFt") BUILTIN(__builtin_matrix_column_major_load, "v.", "nFt") diff --git contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def index 025fef05c8e0..6b94dd857300 100644 --- contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def +++ contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def @@ -402,6 +402,23 @@ BUILTIN(__nvvm_ull2d_rp, "dULLi", "") BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "") BUILTIN(__nvvm_f2h_rn, "Usf", "") +TARGET_BUILTIN(__nvvm_ff2bf16x2_rn, "ZUiff", "", AND(SM_80,PTX70)) +TARGET_BUILTIN(__nvvm_ff2bf16x2_rn_relu, "ZUiff", "", AND(SM_80,PTX70)) +TARGET_BUILTIN(__nvvm_ff2bf16x2_rz, "ZUiff", "", AND(SM_80,PTX70)) +TARGET_BUILTIN(__nvvm_ff2bf16x2_rz_relu, "ZUiff", "", AND(SM_80,PTX70)) + +TARGET_BUILTIN(__nvvm_ff2f16x2_rn, "V2hff", "", AND(SM_80,PTX70)) +TARGET_BUILTIN(__nvvm_ff2f16x2_rn_relu, "V2hff", "", AND(SM_80,PTX70)) +TARGET_BUILTIN(__nvvm_ff2f16x2_rz, "V2hff", "", AND(SM_80,PTX70)) +TARGET_BUILTIN(__nvvm_ff2f16x2_rz_relu, "V2hff", "", AND(SM_80,PTX70)) + +TARGET_BUILTIN(__nvvm_f2bf16_rn, "ZUsf", "", AND(SM_80,PTX70)) +TARGET_BUILTIN(__nvvm_f2bf16_rn_relu, "ZUsf", "", AND(SM_80,PTX70)) +TARGET_BUILTIN(__nvvm_f2bf16_rz, "ZUsf", "", AND(SM_80,PTX70)) +TARGET_BUILTIN(__nvvm_f2bf16_rz_relu, "ZUsf", "", AND(SM_80,PTX70)) + +TARGET_BUILTIN(__nvvm_f2tf32_rna, "ZUif", "", AND(SM_80,PTX70)) + // Bitcast BUILTIN(__nvvm_bitcast_f2i, "if", "") diff --git contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def index 06560415e686..495a036e576f 100644 --- contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def +++ contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def @@ -16,13 +16,13 @@ #endif // Zbb extension -TARGET_BUILTIN(__builtin_riscv_orc_b_32, "ZiZi", "nc", "experimental-zbb") -TARGET_BUILTIN(__builtin_riscv_orc_b_64, "WiWi", "nc", "experimental-zbb,64bit") +TARGET_BUILTIN(__builtin_riscv_orc_b_32, "ZiZi", "nc", "zbb") +TARGET_BUILTIN(__builtin_riscv_orc_b_64, "WiWi", "nc", "zbb,64bit") // Zbc extension -TARGET_BUILTIN(__builtin_riscv_clmul, "LiLiLi", "nc", "experimental-zbc") -TARGET_BUILTIN(__builtin_riscv_clmulh, "LiLiLi", "nc", "experimental-zbc") -TARGET_BUILTIN(__builtin_riscv_clmulr, "LiLiLi", "nc", "experimental-zbc") +TARGET_BUILTIN(__builtin_riscv_clmul, "LiLiLi", "nc", "zbc") +TARGET_BUILTIN(__builtin_riscv_clmulh, "LiLiLi", "nc", "zbc") +TARGET_BUILTIN(__builtin_riscv_clmulr, "LiLiLi", "nc", "zbc") // Zbe extension TARGET_BUILTIN(__builtin_riscv_bcompress_32, "ZiZiZi", "nc", "experimental-zbe") @@ -33,6 +33,10 @@ TARGET_BUILTIN(__builtin_riscv_bdecompress_32, "ZiZiZi", "nc", TARGET_BUILTIN(__builtin_riscv_bdecompress_64, "WiWiWi", "nc", "experimental-zbe,64bit") +// Zbf extension +TARGET_BUILTIN(__builtin_riscv_bfp_32, "ZiZiZi", "nc", "experimental-zbf") +TARGET_BUILTIN(__builtin_riscv_bfp_64, "WiWiWi", "nc", "experimental-zbf,64bit") + // Zbp extension TARGET_BUILTIN(__builtin_riscv_grev_32, "ZiZiZi", "nc", "experimental-zbp") TARGET_BUILTIN(__builtin_riscv_grev_64, "WiWiWi", "nc", "experimental-zbp,64bit") @@ -54,8 +58,14 @@ TARGET_BUILTIN(__builtin_riscv_crc32_w, "LiLi", "nc", "experimental-zbr") TARGET_BUILTIN(__builtin_riscv_crc32c_b, "LiLi", "nc", "experimental-zbr") TARGET_BUILTIN(__builtin_riscv_crc32c_h, "LiLi", "nc", "experimental-zbr") TARGET_BUILTIN(__builtin_riscv_crc32c_w, "LiLi", "nc", "experimental-zbr") -TARGET_BUILTIN(__builtin_riscv_crc32_d, "LiLi", "nc", "experimental-zbr") -TARGET_BUILTIN(__builtin_riscv_crc32c_d, "LiLi", "nc", "experimental-zbr") +TARGET_BUILTIN(__builtin_riscv_crc32_d, "LiLi", "nc", "experimental-zbr,64bit") +TARGET_BUILTIN(__builtin_riscv_crc32c_d, "LiLi", "nc", "experimental-zbr,64bit") + +// Zbt extension +TARGET_BUILTIN(__builtin_riscv_fsl_32, "LiLiLiLi", "nc", "experimental-zbt") +TARGET_BUILTIN(__builtin_riscv_fsr_32, "LiLiLiLi", "nc", "experimental-zbt") +TARGET_BUILTIN(__builtin_riscv_fsl_64, "WiWiWiWi", "nc", "experimental-zbt,64bit") +TARGET_BUILTIN(__builtin_riscv_fsr_64, "WiWiWiWi", "nc", "experimental-zbt,64bit") #undef BUILTIN #undef TARGET_BUILTIN diff --git contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def index bc6208be4560..0669a96b942b 100644 --- contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def +++ contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def @@ -265,10 +265,6 @@ TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_pminsw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_packsswb128, "V16cV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_packssdw128, "V8sV4iV4i", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_packuswb128, "V16cV8sV8s", "ncV:128:", "sse2") @@ -296,9 +292,6 @@ TARGET_BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "ncV:128:", "ssse3") TARGET_BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "ncV:128:", "ssse3") TARGET_BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "ncV:128:", "ssse3") TARGET_BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "ncV:128:", "ssse3") -TARGET_BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "ncV:128:", "ssse3") -TARGET_BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "ncV:128:", "ssse3") -TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "ncV:128:", "ssse3") TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "n", "sse") TARGET_HEADER_BUILTIN(_mm_setcsr, "vUi", "nh","xmmintrin.h", ALL_LANGUAGES, "sse") @@ -380,14 +373,6 @@ TARGET_BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_packusdw128, "V8sV4iV4i", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmaxsb128, "V16cV16cV16c", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmaxsd128, "V4iV4iV4i", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmaxud128, "V4iV4iV4i", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmaxuw128, "V8sV8sV8s", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pmuldq128, "V2OiV4iV4i", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundps, "V4fV4fIi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fIi", "ncV:128:", "sse4.1") @@ -558,9 +543,6 @@ TARGET_BUILTIN(__builtin_ia32_vec_set_v8si, "V8iV8iiIi", "ncV:256:", "avx") // AVX2 TARGET_BUILTIN(__builtin_ia32_mpsadbw256, "V32cV32cV32cIc", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pabsb256, "V32cV32c", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pabsw256, "V16sV16s", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pabsd256, "V8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_packsswb256, "V32cV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_packssdw256, "V16sV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_packuswb256, "V32cV16sV16s", "ncV:256:", "avx2") @@ -586,18 +568,6 @@ TARGET_BUILTIN(__builtin_ia32_phsubd256, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_phsubsw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmaddubsw256, "V16sV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmaddwd256, "V8iV16sV16s", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmaxub256, "V32cV32cV32c", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmaxuw256, "V16sV16sV16s", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmaxud256, "V8iV8iV8i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmaxsb256, "V32cV32cV32c", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmaxsw256, "V16sV16sV16s", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmaxsd256, "V8iV8iV8i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pminub256, "V32cV32cV32c", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pminuw256, "V16sV16sV16s", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pminud256, "V8iV8iV8i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pminsb256, "V32cV32cV32c", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pminsw256, "V16sV16sV16s", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pminsd256, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmovmskb256, "iV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmuldq256, "V4OiV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmulhrsw256, "V16sV16sV16s", "ncV:256:", "avx2") @@ -927,16 +897,6 @@ TARGET_BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "ncV:512:", TARGET_BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pabsd512, "V16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pabsq512, "V8OiV8Oi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmaxsd512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmaxsq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmaxud512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmaxuq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pminsd512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pminsq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pminud512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pminuq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8OiV16iV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8OiV16iV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "nV:512:", "avx512f") @@ -1045,8 +1005,6 @@ TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx5 TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8OiV8OiIiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pabsb512, "V64cV64c", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pabsw512, "V32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_packssdw512, "V32sV16iV16i", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_packsswb512, "V64cV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_packusdw512, "V32sV16iV16i", "ncV:512:", "avx512bw") @@ -1057,14 +1015,6 @@ TARGET_BUILTIN(__builtin_ia32_paddusb512, "V64cV64cV64c", "ncV:512:", "avx512bw" TARGET_BUILTIN(__builtin_ia32_paddusw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pavgb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pavgw512, "V32sV32sV32s", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pmaxsb512, "V64cV64cV64c", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pmaxsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pmaxub512, "V64cV64cV64c", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pmaxuw512, "V32sV32sV32s", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pminsb512, "V64cV64cV64c", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pminsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pminub512, "V64cV64cV64c", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pminuw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pshufb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psubsb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psubsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") @@ -1198,16 +1148,6 @@ TARGET_BUILTIN(__builtin_ia32_getexppd128_mask, "V2dV2dV2dUc", "ncV:128:", "avx5 TARGET_BUILTIN(__builtin_ia32_getexppd256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_getexpps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_getexpps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pabsq128, "V2OiV2Oi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pabsq256, "V4OiV4Oi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxsq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxsq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxuq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxuq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminsq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminsq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminuq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminuq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rndscalepd_128_mask, "V2dV2dIiV2dUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rndscalepd_256_mask, "V4dV4dIiV4dUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rndscaleps_128_mask, "V4fV4fIiV4fUc", "ncV:128:", "avx512vl") @@ -2075,8 +2015,6 @@ TARGET_BUILTIN(__builtin_ia32_selectsd_128, "V2dUcV2dV2d", "ncV:128:", "avx512f" // generic reduction intrinsics TARGET_BUILTIN(__builtin_ia32_reduce_add_d512, "iV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_reduce_add_q512, "OiV8Oi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_and_d512, "iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_and_q512, "OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_reduce_fadd_pd512, "ddV8d", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_reduce_fadd_ps512, "ffV16f", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_reduce_fadd_ph512, "xxV32x", "ncV:512:", "avx512fp16") @@ -2099,16 +2037,6 @@ TARGET_BUILTIN(__builtin_ia32_reduce_fmul_ph256, "xxV16x", "ncV:256:", "avx512fp TARGET_BUILTIN(__builtin_ia32_reduce_fmul_ph128, "xxV8x", "ncV:128:", "avx512fp16,avx512vl") TARGET_BUILTIN(__builtin_ia32_reduce_mul_d512, "iV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_reduce_mul_q512, "OiV8Oi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_or_d512, "iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_or_q512, "OiV8Oi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_smax_d512, "iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_smax_q512, "OiV8Oi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_smin_d512, "iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_smin_q512, "OiV8Oi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_umax_d512, "iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_umax_q512, "OiV8Oi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_umin_d512, "iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_reduce_umin_q512, "OiV8Oi", "ncV:512:", "avx512f") // MONITORX/MWAITX TARGET_BUILTIN(__builtin_ia32_monitorx, "vvC*UiUi", "n", "mwaitx") diff --git contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def index 723302f108e2..0da875525c0c 100644 --- contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def +++ contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def @@ -64,7 +64,7 @@ CODEGENOPT(DisableLifetimeMarkers, 1, 0) ///< Don't emit any lifetime markers CODEGENOPT(DisableO0ImplyOptNone , 1, 0) ///< Don't annonate function with optnone at O0 CODEGENOPT(ExperimentalStrictFloatingPoint, 1, 0) ///< Enables the new, experimental ///< strict floating point. -CODEGENOPT(EnableNoundefAttrs, 1, 0) ///< Enable emitting `noundef` attributes on IR call arguments and return values +CODEGENOPT(DisableNoundefAttrs, 1, 0) ///< Disable emitting `noundef` attributes on IR call arguments and return values CODEGENOPT(LegacyPassManager, 1, 0) ///< Use the legacy pass manager. CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new ///< pass manager. @@ -107,6 +107,8 @@ CODEGENOPT(CFProtectionReturn , 1, 0) ///< if -fcf-protection is ///< set to full or return. CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection is ///< set to full or branch. +CODEGENOPT(IBTSeal, 1, 0) ///< set to optimize CFProtectionBranch. + CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is ///< enabled. CODEGENOPT(StackSizeSection , 1, 0) ///< Set when -fstack-size-section is enabled. @@ -139,6 +141,9 @@ VALUE_CODEGENOPT(XRaySelectedFunctionGroup, 32, 0) VALUE_CODEGENOPT(PatchableFunctionEntryCount , 32, 0) ///< Number of NOPs at function entry VALUE_CODEGENOPT(PatchableFunctionEntryOffset , 32, 0) +CODEGENOPT(HotPatch, 1, 0) ///< Supports the Microsoft /HOTPATCH flag and + ///< generates a 'patchable-function' attribute. + CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled. CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled. CODEGENOPT(MNopMCount , 1, 0) ///< Set when -mnop-mcount is enabled. @@ -231,6 +236,9 @@ CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in ENUM_CODEGENOPT(SanitizeAddressDtor, llvm::AsanDtorKind, 2, llvm::AsanDtorKind::Global) ///< Set how ASan global ///< destructors are emitted. +CODEGENOPT(SanitizeMemoryParamRetval, 1, 0) ///< Enable detection of uninitialized + ///< parameters and return values + ///< in MemorySanitizer CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection ///< in MemorySanitizer CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI. diff --git contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h index 33ec03a17136..5a5c2689c689 100644 --- contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h +++ contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h @@ -307,7 +307,7 @@ public: std::shared_ptr<llvm::Regex> Regex; /// By default, optimization remark is missing. - OptRemark() : Kind(RK_Missing), Pattern(""), Regex(nullptr) {} + OptRemark() : Kind(RK_Missing), Regex(nullptr) {} /// Returns true iff the optimization remark holds a valid regular /// expression. diff --git contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h index 918dc7c8becc..df16827debfc 100644 --- contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h +++ contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_BASIC_DARWIN_SDK_INFO_H -#define LLVM_CLANG_BASIC_DARWIN_SDK_INFO_H +#ifndef LLVM_CLANG_BASIC_DARWINSDKINFO_H +#define LLVM_CLANG_BASIC_DARWINSDKINFO_H #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" @@ -57,6 +57,20 @@ public: llvm::Triple::MacOSX, llvm::Triple::UnknownEnvironment); } + /// Returns the os-environment mapping pair that's used to represent the + /// iOS -> watchOS version mapping. + static inline constexpr OSEnvPair iOStoWatchOSPair() { + return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, + llvm::Triple::WatchOS, llvm::Triple::UnknownEnvironment); + } + + /// Returns the os-environment mapping pair that's used to represent the + /// iOS -> tvOS version mapping. + static inline constexpr OSEnvPair iOStoTvOSPair() { + return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, + llvm::Triple::TvOS, llvm::Triple::UnknownEnvironment); + } + private: StorageType Value; @@ -154,4 +168,4 @@ Expected<Optional<DarwinSDKInfo>> parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, } // end namespace clang -#endif // LLVM_CLANG_BASIC_DARWIN_SDK_INFO_H +#endif // LLVM_CLANG_BASIC_DARWINSDKINFO_H diff --git contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td index ab2c738a2ace..c932c9057278 100644 --- contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td +++ contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td @@ -84,6 +84,7 @@ class Diagnostic<string text, DiagClass DC, Severity defaultmapping> { bit AccessControl = 0; bit WarningNoWerror = 0; bit ShowInSystemHeader = 0; + bit ShowInSystemMacro = 1; bit Deferrable = 0; Severity DefaultSeverity = defaultmapping; DiagGroup Group; @@ -108,6 +109,14 @@ class SuppressInSystemHeader { bit ShowInSystemHeader = 0; } +class ShowInSystemMacro { + bit ShowInSystemMacro = 1; +} + +class SuppressInSystemMacro { + bit ShowInSystemMacro = 0; +} + class Deferrable { bit Deferrable = 1; } @@ -159,4 +168,3 @@ include "DiagnosticParseKinds.td" include "DiagnosticRefactoringKinds.td" include "DiagnosticSemaKinds.td" include "DiagnosticSerializationKinds.td" - diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticAST.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticAST.h index 76c31ad9508e..24ef2689eac0 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticAST.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticAST.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define ASTSTART #include "clang/Basic/DiagnosticASTKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td index d788c8517914..a89bdff1a10c 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -590,4 +590,9 @@ def warn_padded_struct_size : Warning< InGroup<Padded>, DefaultIgnore; def warn_unnecessary_packed : Warning< "packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore; + +// -Wunaligned-access +def warn_unaligned_access : Warning< + "field %1 within %0 is less aligned than %2 and is usually due to %0 being " + "packed, which can lead to unaligned accesses">, InGroup<UnalignedAccess>, DefaultIgnore; } diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysis.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysis.h index f9037cc8d75a..676b58f7d6ef 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysis.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysis.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define ANALYSISSTART #include "clang/Basic/DiagnosticAnalysisKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticComment.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticComment.h index 6e011bfcebab..17c0053e9a33 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticComment.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticComment.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define COMMENTSTART #include "clang/Basic/DiagnosticCommentKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTU.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTU.h index ded85ec3f840..4341bf327b69 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTU.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTU.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define CROSSTUSTART #include "clang/Basic/DiagnosticCrossTUKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriver.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriver.h index cecd8fd6b4d5..6931bd46542e 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriver.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriver.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define DRIVERSTART #include "clang/Basic/DiagnosticDriverKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td index a7fd2f26478c..e635be6b6d1b 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -116,10 +116,6 @@ def warn_drv_unsupported_option_for_target : Warning< "ignoring '%0' option as it is not currently supported for target '%1'">, InGroup<OptionIgnored>; -def warn_drv_spirv_linking_multiple_inputs_unsupported: Warning< - "Linking multiple input files is not supported for SPIR-V yet">, - InGroup<OptionIgnored>; - def err_drv_invalid_thread_model_for_target : Error< "invalid thread model '%0' in '%1' for this target">; def err_drv_invalid_linker_name : Error< @@ -384,6 +380,9 @@ def warn_drv_deprecated_arg : Warning< "argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>; def warn_drv_assuming_mfloat_abi_is : Warning< "unknown platform, assuming -mfloat-abi=%0">; +def warn_drv_unsupported_float_abi_by_lib : Warning< + "float ABI '%0' is not supported by current library">, + InGroup<DiagGroup<"unsupported-abi">>; def warn_ignoring_ftabstop_value : Warning< "ignoring invalid -ftabstop value '%0', using default value %1">; def warn_drv_overriding_flag_option : Warning< diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h index 430da6f724ed..76d893a5ccf8 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H -#define LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H +#ifndef LLVM_CLANG_BASIC_DIAGNOSTICERROR_H +#define LLVM_CLANG_BASIC_DIAGNOSTICERROR_H #include "clang/Basic/PartialDiagnostic.h" #include "llvm/Support/Error.h" @@ -57,4 +57,4 @@ private: } // end namespace clang -#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H +#endif // LLVM_CLANG_BASIC_DIAGNOSTICERROR_H diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontend.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontend.h index f57c587fb469..ab4e855f2de0 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontend.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontend.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define FRONTENDSTART #include "clang/Basic/DiagnosticFrontendKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td index c0642efaee4e..608e16147b1c 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td @@ -241,6 +241,7 @@ def Documentation : DiagGroup<"documentation", def EmptyBody : DiagGroup<"empty-body">; def Exceptions : DiagGroup<"exceptions">; +def DeclarationAfterStatement : DiagGroup<"declaration-after-statement">; def GNUEmptyInitializer : DiagGroup<"gnu-empty-initializer">; def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">; @@ -542,6 +543,7 @@ def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">; def OrderedCompareFunctionPointers : DiagGroup<"ordered-compare-function-pointers">; def Packed : DiagGroup<"packed">; def Padded : DiagGroup<"padded">; +def UnalignedAccess : DiagGroup<"unaligned-access">; def PessimizingMove : DiagGroup<"pessimizing-move">; def ReturnStdMove : DiagGroup<"return-std-move">; diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h index 375930c14848..ba5f5acc8ce6 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h @@ -67,7 +67,7 @@ namespace clang { // Get typedefs for common diagnostics. enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, CATEGORY, \ - NOWERROR, SHOWINSYSHEADER, DEFFERABLE) \ + NOWERROR, SHOWINSYSHEADER, SHOWINSYSMACRO, DEFFERABLE) \ ENUM, #define COMMONSTART #include "clang/Basic/DiagnosticCommonKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticLex.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticLex.h index 7a3128de3b82..5f237085ae03 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticLex.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticLex.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define LEXSTART #include "clang/Basic/DiagnosticLexKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticParse.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticParse.h index d066d3f71a25..81a8185d25fb 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticParse.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticParse.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define PARSESTART #include "clang/Basic/DiagnosticParseKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td index 9dc036c03faa..770ddb3ab16f 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1344,15 +1344,17 @@ def warn_omp_unknown_assumption_clause_without_args def note_omp_assumption_clause_continue_here : Note<"the ignored tokens spans until here">; def err_omp_declare_target_unexpected_clause: Error< - "unexpected '%0' clause, only %select{'device_type'|'to' or 'link'|'to', 'link' or 'device_type'}1 clauses expected">; + "unexpected '%0' clause, only %select{'device_type'|'to' or 'link'|'to', 'link' or 'device_type'|'device_type', 'indirect'|'to', 'link', 'device_type' or 'indirect'}1 clauses expected">; def err_omp_begin_declare_target_unexpected_implicit_to_clause: Error< "unexpected '(', only 'to', 'link' or 'device_type' clauses expected for 'begin declare target' directive">; def err_omp_declare_target_unexpected_clause_after_implicit_to: Error< "unexpected clause after an implicit 'to' clause">; def err_omp_declare_target_missing_to_or_link_clause: Error< - "expected at least one 'to' or 'link' clause">; + "expected at least one %select{'to' or 'link'|'to', 'link' or 'indirect'}0 clause">; def err_omp_declare_target_multiple : Error< "%0 appears multiple times in clauses on the same declare target directive">; +def err_omp_declare_target_indirect_device_type: Error< + "only 'device_type(any)' clause is allowed with indirect clause">; def err_omp_expected_clause: Error< "expected at least one clause on '#pragma omp %0' directive">; def err_omp_mapper_illegal_identifier : Error< @@ -1374,7 +1376,7 @@ def warn_omp_declare_variant_string_literal_or_identifier "%select{set|selector|property}0; " "%select{set|selector|property}0 skipped">, InGroup<OpenMPClauses>; -def warn_unknown_begin_declare_variant_isa_trait +def warn_unknown_declare_variant_isa_trait : Warning<"isa trait '%0' is not known to the current target; verify the " "spelling or consider restricting the context selector with the " "'arch' selector further">, diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticRefactoring.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticRefactoring.h index fc7564047a24..9b628dbeb7c2 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticRefactoring.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticRefactoring.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define REFACTORINGSTART #include "clang/Basic/DiagnosticRefactoringKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticSema.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticSema.h index 7323167aeee8..45014fe21271 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticSema.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticSema.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define SEMASTART #include "clang/Basic/DiagnosticSemaKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td index f2089bfda04d..a8cf00c1263f 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -197,7 +197,8 @@ def ext_flexible_array_init : Extension< // C++20 designated initializers def ext_cxx_designated_init : Extension< - "designated initializers are a C++20 extension">, InGroup<CXX20Designator>; + "designated initializers are a C++20 extension">, InGroup<CXX20Designator>, + SuppressInSystemMacro; def warn_cxx17_compat_designated_init : Warning< "designated initializers are incompatible with C++ standards before C++20">, InGroup<CXXPre20CompatPedantic>, DefaultIgnore; @@ -449,7 +450,7 @@ def warn_decl_shadow : "typedef in %2|" "type alias in %2|" "structured binding}1">, - InGroup<Shadow>, DefaultIgnore; + InGroup<Shadow>, DefaultIgnore, SuppressInSystemMacro; def warn_decl_shadow_uncaptured_local : Warning<warn_decl_shadow.Text>, InGroup<ShadowUncapturedLocal>, DefaultIgnore; @@ -1695,9 +1696,6 @@ def err_missing_exception_specification : Error< def ext_missing_exception_specification : ExtWarn< err_missing_exception_specification.Text>, InGroup<DiagGroup<"missing-exception-spec">>; -def ext_ms_missing_exception_specification : ExtWarn< - err_missing_exception_specification.Text>, - InGroup<MicrosoftExceptionSpec>; def err_noexcept_needs_constant_expression : Error< "argument to noexcept specifier must be a constant expression">; def err_exception_spec_not_parsed : Error< @@ -3944,7 +3942,8 @@ def warn_cast_align : Warning< "cast from %0 to %1 increases required alignment from %2 to %3">, InGroup<CastAlign>, DefaultIgnore; def warn_old_style_cast : Warning< - "use of old-style cast">, InGroup<OldStyleCast>, DefaultIgnore; + "use of old-style cast">, InGroup<OldStyleCast>, DefaultIgnore, + SuppressInSystemMacro; // Separate between casts to void* and non-void* pointers. // Some APIs use (abuse) void* for something like a user context, @@ -5785,7 +5784,7 @@ def err_typecheck_invalid_restrict_invalid_pointee : Error< def ext_typecheck_zero_array_size : Extension< "zero size arrays are an extension">, InGroup<ZeroLengthArray>; def err_typecheck_zero_array_size : Error< - "zero-length arrays are not permitted in C++">; + "zero-length arrays are not permitted in %select{C++|SYCL device code}0">; def err_array_size_non_int : Error<"size of array has non-integer type %0">; def err_init_element_not_constant : Error< "initializer element is not a compile-time constant">; @@ -7804,6 +7803,11 @@ def err_expected_class_or_namespace : Error<"%0 is not a class" "%select{ or namespace|, namespace, or enumeration}1">; def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here " "because namespace %1 does not enclose namespace %2">; +def err_export_non_namespace_scope_name : Error< + "cannot export %0 as it is not at namespace scope">; +def err_redeclaration_non_exported : Error < + "cannot export redeclaration %0 here since the previous declaration is not " + "exported">; def err_invalid_declarator_global_scope : Error< "definition or redeclaration of %0 cannot name the global scope">; def err_invalid_declarator_in_function : Error< @@ -9370,6 +9374,9 @@ def warn_printf_ObjCflags_without_ObjCConversion: Warning< def warn_printf_invalid_objc_flag: Warning< "'%0' is not a valid object format flag">, InGroup<Format>; +def warn_printf_narg_not_supported : Warning< + "'%%n' specifier not supported on this platform">, + InGroup<Format>; def warn_scanf_scanlist_incomplete : Warning< "no closing ']' for '%%[' in scanf format string">, InGroup<Format>; @@ -9549,7 +9556,8 @@ def err_generic_sel_multi_match : Error< // Blocks def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks" - " or %select{pick a deployment target that supports them|for OpenCL 2.0}0">; + " or %select{pick a deployment target that supports them|for OpenCL C 2.0" + " or OpenCL C 3.0 with __opencl_c_device_enqueue feature}0">; def err_block_returning_array_function : Error< "block cannot return %select{array|function}0 type %1">; @@ -9862,8 +9870,11 @@ def err_constant_integer_arg_type : Error< "argument to %0 must be a constant integer">; def ext_mixed_decls_code : Extension< - "ISO C90 forbids mixing declarations and code">, - InGroup<DiagGroup<"declaration-after-statement">>; + "mixing declarations and code is a C99 extension">, + InGroup<DeclarationAfterStatement>; +def warn_mixed_decls_code : Warning< + "mixing declarations and code is incompatible with standards before C99">, + InGroup<DeclarationAfterStatement>, DefaultIgnore; def err_non_local_variable_decl_in_for : Error< "declaration of non-local variable in 'for' loop">; @@ -10813,11 +10824,6 @@ def err_omp_non_lvalue_in_map_or_motion_clauses: Error< "expected addressable lvalue in '%0' clause">; def err_omp_var_expected : Error< "expected variable of the '%0' type%select{|, not %2}1">; -def warn_unknown_declare_variant_isa_trait - : Warning<"isa trait '%0' is not known to the current target; verify the " - "spelling or consider restricting the context selector with the " - "'arch' selector further">, - InGroup<SourceUsesOpenMP>; def err_omp_non_pointer_type_array_shaping_base : Error< "expected expression with a pointer to a complete type as a base of an array " "shaping operation">; @@ -11047,7 +11053,7 @@ def warn_deprecated_coroutine_namespace : Warning< "use std::%0 instead">, InGroup<DeprecatedExperimentalCoroutine>; def err_mixed_use_std_and_experimental_namespace_for_coroutine : Error< - "mixed use of std and std::experimental namespaces for " + "conflicting mixed use of std and std::experimental namespaces for " "coroutine components">; def err_implicit_coroutine_std_nothrow_type_not_found : Error< "std::nothrow was not found; include <new> before defining a coroutine which " @@ -11443,6 +11449,9 @@ def warn_sycl_kernel_num_of_function_params : Warning< def warn_sycl_kernel_return_type : Warning< "function template with 'sycl_kernel' attribute must have a 'void' return type">, InGroup<IgnoredAttributes>; +def err_sycl_special_type_num_init_method : Error< + "types with 'sycl_special_class' attribute must have one and only one '__init' " + "method defined">; def err_bit_int_bad_size : Error<"%select{signed|unsigned}0 _BitInt must " "have a bit size of at least %select{2|1}0">; @@ -11466,7 +11475,7 @@ def warn_tcb_enforcement_violation : Warning< // RISC-V builtin required extension warning def err_riscv_builtin_requires_extension : Error< - "builtin requires '%0' extension support to be enabled">; + "builtin requires at least one of the following extensions support to be enabled : %0">; def err_riscv_builtin_invalid_lmul : Error< "LMUL argument must be in the range [0,3] or [5,7]">; } // end of sema component. diff --git contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerialization.h contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerialization.h index b3d99fb3feaa..0c622a565773 100644 --- contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerialization.h +++ contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerialization.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ ENUM, #define SERIALIZATIONSTART #include "clang/Basic/DiagnosticSerializationKinds.inc" diff --git contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h index edb8031a20b8..ac8e790230fc 100644 --- contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h +++ contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h @@ -19,6 +19,7 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorOr.h" namespace clang { diff --git contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h index 19c967efcc42..aaf1297c1a64 100644 --- contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h +++ contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h @@ -458,6 +458,10 @@ public: /// 7.1.3, C++ [lib.global.names]). ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const; + /// If the identifier is an "uglified" reserved name, return a cleaned form. + /// e.g. _Foo => Foo. Otherwise, just returns the name. + StringRef deuglifiedName() const; + /// Provide less than operator for lexicographical sorting. bool operator<(const IdentifierInfo &RHS) const { return getName() < RHS.getName(); diff --git contrib/llvm-project/clang/include/clang/Basic/LangOptions.h contrib/llvm-project/clang/include/clang/Basic/LangOptions.h index 35b33c2e0971..09afa641acf9 100644 --- contrib/llvm-project/clang/include/clang/Basic/LangOptions.h +++ contrib/llvm-project/clang/include/clang/Basic/LangOptions.h @@ -124,6 +124,7 @@ public: MSVC2017_5 = 1912, MSVC2017_7 = 1914, MSVC2019 = 1920, + MSVC2019_5 = 1925, MSVC2019_8 = 1928, }; diff --git contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h index d6cb1a210519..512bcb1e6ef1 100644 --- contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h +++ contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h @@ -212,6 +212,15 @@ private: bool isEnabled(llvm::StringRef Ext) const; OpenCLOptionInfoMap OptMap; + + // First feature in a pair requires the second one to be supported. + using FeatureDepEntry = std::pair<llvm::StringRef, llvm::StringRef>; + using FeatureDepList = llvm::SmallVector<FeatureDepEntry, 8>; + + static const FeatureDepList DependentFeaturesList; + + // Extensions and equivalent feature pairs. + static const llvm::StringMap<llvm::StringRef> FeatureExtensionMap; }; } // end namespace clang diff --git contrib/llvm-project/clang/include/clang/Basic/OperatorPrecedence.h contrib/llvm-project/clang/include/clang/Basic/OperatorPrecedence.h index 61ac7ad62f6b..9bda3eb28fdf 100644 --- contrib/llvm-project/clang/include/clang/Basic/OperatorPrecedence.h +++ contrib/llvm-project/clang/include/clang/Basic/OperatorPrecedence.h @@ -49,4 +49,4 @@ prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, } // end namespace clang -#endif // LLVM_CLANG_OPERATOR_PRECEDENCE_H +#endif // LLVM_CLANG_BASIC_OPERATORPRECEDENCE_H diff --git contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h index 9fb70bff7fee..ddee6821e2e1 100644 --- contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h +++ contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h @@ -28,9 +28,6 @@ namespace clang { -class DeclContext; -class IdentifierInfo; - class PartialDiagnostic : public StreamingDiagnostic { private: // NOTE: Sema assumes that PartialDiagnostic is location-invariant diff --git contrib/llvm-project/clang/include/clang/Basic/PragmaKinds.h contrib/llvm-project/clang/include/clang/Basic/PragmaKinds.h index 82c0d5f0a551..176bbc9ac7ca 100644 --- contrib/llvm-project/clang/include/clang/Basic/PragmaKinds.h +++ contrib/llvm-project/clang/include/clang/Basic/PragmaKinds.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_BASIC_PRAGMA_KINDS_H -#define LLVM_CLANG_BASIC_PRAGMA_KINDS_H +#ifndef LLVM_CLANG_BASIC_PRAGMAKINDS_H +#define LLVM_CLANG_BASIC_PRAGMAKINDS_H namespace clang { diff --git contrib/llvm-project/clang/include/clang/Basic/ProfileList.h contrib/llvm-project/clang/include/clang/Basic/ProfileList.h index 989c36549a3d..aa472f126818 100644 --- contrib/llvm-project/clang/include/clang/Basic/ProfileList.h +++ contrib/llvm-project/clang/include/clang/Basic/ProfileList.h @@ -10,8 +10,8 @@ // functions. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_BASIC_INSTRPROFLIST_H -#define LLVM_CLANG_BASIC_INSTRPROFLIST_H +#ifndef LLVM_CLANG_BASIC_PROFILELIST_H +#define LLVM_CLANG_BASIC_PROFILELIST_H #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/LLVM.h" @@ -21,10 +21,6 @@ #include "llvm/ADT/StringRef.h" #include <memory> -namespace llvm { -class SpecialCaseList; -} - namespace clang { class ProfileSpecialCaseList; diff --git contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def index f6ef62a64636..1d4024dfb20d 100644 --- contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def +++ contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def @@ -30,8 +30,8 @@ // // - ElBits is the size of one element in bits (SEW). // -// - NF is the number of fields (NFIELDS) used in the Zvlsseg instructions -// (TODO). +// - NF is the number of fields (NFIELDS) used in the Load/Store Segment +// instructions (TODO). // // - IsSigned is true for vectors of signed integer elements and // for vectors of floating-point elements. diff --git contrib/llvm-project/clang/include/clang/Basic/TargetID.h contrib/llvm-project/clang/include/clang/Basic/TargetID.h index 1a9785574d06..2579276fc034 100644 --- contrib/llvm-project/clang/include/clang/Basic/TargetID.h +++ contrib/llvm-project/clang/include/clang/Basic/TargetID.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_BASIC_TARGET_ID_H -#define LLVM_CLANG_BASIC_TARGET_ID_H +#ifndef LLVM_CLANG_BASIC_TARGETID_H +#define LLVM_CLANG_BASIC_TARGETID_H #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" @@ -21,7 +21,7 @@ namespace clang { /// postfixed by a plus or minus sign delimited by colons, e.g. /// gfx908:xnack+:sramecc-. Each processor have a limited /// number of predefined features when showing up in a target ID. -const llvm::SmallVector<llvm::StringRef, 4> +llvm::SmallVector<llvm::StringRef, 4> getAllPossibleTargetIDFeatures(const llvm::Triple &T, llvm::StringRef Processor); diff --git contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h index 437feba85e23..686a365b8c12 100644 --- contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h +++ contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h @@ -47,9 +47,6 @@ class DiagnosticsEngine; class LangOptions; class CodeGenOptions; class MacroBuilder; -class QualType; -class SourceLocation; -class SourceManager; namespace Builtin { struct Info; } @@ -215,6 +212,7 @@ protected: unsigned char RegParmMax, SSERegParmMax; TargetCXXABI TheCXXABI; const LangASMap *AddrSpaceMap; + unsigned ProgramAddrSpace; mutable StringRef PlatformName; mutable VersionTuple PlatformMinVersion; @@ -770,6 +768,9 @@ public: return getTypeWidth(IntMaxType); } + /// Return the address space for functions for the given target. + unsigned getProgramAddressSpace() const { return ProgramAddrSpace; } + // Return the size of unwind_word for this target. virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); } diff --git contrib/llvm-project/clang/include/clang/Basic/arm_neon.td contrib/llvm-project/clang/include/clang/Basic/arm_neon.td index 173003d171ee..2e9798129fdf 100644 --- contrib/llvm-project/clang/include/clang/Basic/arm_neon.td +++ contrib/llvm-project/clang/include/clang/Basic/arm_neon.td @@ -80,10 +80,8 @@ def OP_QDMULH_N : Op<(call "vqdmulh", $p0, (dup $p1))>; def OP_QDMULH_LN : Op<(call "vqdmulh", $p0, (call_mangled "splat_lane", $p1, $p2))>; def OP_QRDMULH_LN : Op<(call "vqrdmulh", $p0, (call_mangled "splat_lane", $p1, $p2))>; def OP_QRDMULH_N : Op<(call "vqrdmulh", $p0, (dup $p1))>; -def OP_QRDMLAH : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1, $p2))>; -def OP_QRDMLSH : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1, $p2))>; -def OP_QRDMLAH_LN : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1, (call_mangled "splat_lane", $p2, $p3)))>; -def OP_QRDMLSH_LN : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1, (call_mangled "splat_lane", $p2, $p3)))>; +def OP_QRDMLAH_LN : Op<(call "vqrdmlah", $p0, $p1, (call_mangled "splat_lane", $p2, $p3))>; +def OP_QRDMLSH_LN : Op<(call "vqrdmlsh", $p0, $p1, (call_mangled "splat_lane", $p2, $p3))>; def OP_FMS_LN : Op<(call "vfma_lane", $p0, (op "-", $p1), $p2, $p3)>; def OP_FMS_LNQ : Op<(call "vfma_laneq", $p0, (op "-", $p1), $p2, $p3)>; def OP_TRN1 : Op<(shuffle $p0, $p1, (interleave (decimate mask0, 2), @@ -185,10 +183,10 @@ def OP_SCALAR_QDMULL_LN : ScalarMulOp<"vqdmull">; def OP_SCALAR_QDMULH_LN : ScalarMulOp<"vqdmulh">; def OP_SCALAR_QRDMULH_LN : ScalarMulOp<"vqrdmulh">; -def OP_SCALAR_QRDMLAH_LN : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1, - (call "vget_lane", $p2, $p3)))>; -def OP_SCALAR_QRDMLSH_LN : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1, - (call "vget_lane", $p2, $p3)))>; +def OP_SCALAR_QRDMLAH_LN : Op<(call "vqrdmlah", $p0, $p1, + (call "vget_lane", $p2, $p3))>; +def OP_SCALAR_QRDMLSH_LN : Op<(call "vqrdmlsh", $p0, $p1, + (call "vget_lane", $p2, $p3))>; def OP_SCALAR_HALF_GET_LN : Op<(bitcast "float16_t", (call "vget_lane", @@ -326,8 +324,8 @@ def VQDMULH : SInst<"vqdmulh", "...", "siQsQi">; def VQRDMULH : SInst<"vqrdmulh", "...", "siQsQi">; let ArchGuard = "defined(__ARM_FEATURE_QRDMX)" in { -def VQRDMLAH : SOpInst<"vqrdmlah", "....", "siQsQi", OP_QRDMLAH>; -def VQRDMLSH : SOpInst<"vqrdmlsh", "....", "siQsQi", OP_QRDMLSH>; +def VQRDMLAH : SInst<"vqrdmlah", "....", "siQsQi">; +def VQRDMLSH : SInst<"vqrdmlsh", "....", "siQsQi">; } def VQDMLAL : SInst<"vqdmlal", "(>Q)(>Q)..", "si">; @@ -1400,11 +1398,11 @@ def SCALAR_SQRDMULH : SInst<"vqrdmulh", "111", "SsSi">; let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in { //////////////////////////////////////////////////////////////////////////////// // Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half -def SCALAR_SQRDMLAH : SOpInst<"vqrdmlah", "1111", "SsSi", OP_QRDMLAH>; +def SCALAR_SQRDMLAH : SInst<"vqrdmlah", "1111", "SsSi">; //////////////////////////////////////////////////////////////////////////////// // Signed Saturating Rounding Doubling Multiply Subtract Returning High Half -def SCALAR_SQRDMLSH : SOpInst<"vqrdmlsh", "1111", "SsSi", OP_QRDMLSH>; +def SCALAR_SQRDMLSH : SInst<"vqrdmlsh", "1111", "SsSi">; } //////////////////////////////////////////////////////////////////////////////// diff --git contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td index cc242da7f1ca..6451e77e77f6 100644 --- contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td +++ contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td @@ -215,10 +215,10 @@ class RVVBuiltin<string suffix, string prototype, string type_range, // an automatic definition in header is emitted. string HeaderCode = ""; - // Sub extension of vector spec. Currently only support Zvlsseg. - string RequiredExtension = ""; + // Features required to enable for this builtin. + list<string> RequiredFeatures = []; - // Number of fields for Zvlsseg. + // Number of fields for Load/Store Segment instructions. int NF = 1; } @@ -595,6 +595,7 @@ let HasNoMaskedOverloaded = false, ManualCodegen = [{ IntrinsicTypes = {ResultType, Ops[1]->getType()}; Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo()); + Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType)); }], ManualCodegenMask= [{ // Move mask to right before vl. @@ -628,6 +629,7 @@ multiclass RVVVLEFFBuiltin<list<string> types> { Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo()); Value *NewVL = Ops[1]; Ops.erase(Ops.begin() + 1); + Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType)); llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes); llvm::Value *LoadValue = Builder.CreateCall(F, Ops, ""); llvm::Value *V = Builder.CreateExtractValue(LoadValue, {0}); @@ -677,6 +679,7 @@ multiclass RVVVLSEBuiltin<list<string> types> { ManualCodegen = [{ IntrinsicTypes = {ResultType, Ops[2]->getType()}; Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo()); + Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType)); }], ManualCodegenMask= [{ // Move mask to right before vl. @@ -698,6 +701,7 @@ multiclass RVVIndexedLoad<string op> { let ManualCodegen = [{ IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType()}; Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo()); + Ops.insert(Ops.begin(), llvm::UndefValue::get(ResultType)); }], ManualCodegenMask = [{ // Move mask to right before vl. @@ -707,7 +711,7 @@ multiclass RVVIndexedLoad<string op> { Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo()); }] in { foreach type = TypeList in { - foreach eew_list = EEWList in { + foreach eew_list = EEWList[0-2] in { defvar eew = eew_list[0]; defvar eew_type = eew_list[1]; let Name = op # eew # "_v", IRName = op, IRNameMask = op # "_mask" in { @@ -717,6 +721,15 @@ multiclass RVVIndexedLoad<string op> { } } } + defvar eew64 = "64"; + defvar eew64_type = "(Log2EEW:6)"; + let Name = op # eew64 # "_v", IRName = op, IRNameMask = op # "_mask", + RequiredFeatures = ["RV64"] in { + def: RVVBuiltin<"v", "vPCe" # eew64_type # "Uv", type>; + if !not(IsFloat<type>.val) then { + def: RVVBuiltin<"Uv", "UvPCUe" # eew64_type # "Uv", type>; + } + } } } } @@ -797,7 +810,7 @@ multiclass RVVIndexedStore<string op> { IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType(), Ops[4]->getType()}; }] in { foreach type = TypeList in { - foreach eew_list = EEWList in { + foreach eew_list = EEWList[0-2] in { defvar eew = eew_list[0]; defvar eew_type = eew_list[1]; let Name = op # eew # "_v", IRName = op, IRNameMask = op # "_mask" in { @@ -807,6 +820,15 @@ multiclass RVVIndexedStore<string op> { } } } + defvar eew64 = "64"; + defvar eew64_type = "(Log2EEW:6)"; + let Name = op # eew64 # "_v", IRName = op, IRNameMask = op # "_mask", + RequiredFeatures = ["RV64"] in { + def : RVVBuiltin<"v", "0Pe" # eew64_type # "Uvv", type>; + if !not(IsFloat<type>.val) then { + def : RVVBuiltin<"Uv", "0PUe" # eew64_type # "UvUv", type>; + } + } } } } @@ -1549,7 +1571,6 @@ defm vle32ff: RVVVLEFFBuiltin<["i", "f"]>; defm vle64ff: RVVVLEFFBuiltin<["l", "d"]>; // 7.8 Vector Load/Store Segment Instructions -let RequiredExtension = "Zvlsseg" in { defm : RVVUnitStridedSegLoad<"vlseg">; defm : RVVUnitStridedSegLoadFF<"vlseg">; defm : RVVStridedSegLoad<"vlsseg">; @@ -1559,7 +1580,6 @@ defm : RVVUnitStridedSegStore<"vsseg">; defm : RVVStridedSegStore<"vssseg">; defm : RVVIndexedSegStore<"vsuxseg">; defm : RVVIndexedSegStore<"vsoxseg">; -} // 12. Vector Integer Arithmetic Instructions // 12.1. Vector Single-Width Integer Add and Subtract @@ -1652,11 +1672,13 @@ defm vmax : RVVSignedBinBuiltinSet; // 12.10. Vector Single-Width Integer Multiply Instructions defm vmul : RVVIntBinBuiltinSet; +let RequiredFeatures = ["FullMultiply"] in { defm vmulh : RVVSignedBinBuiltinSet; defm vmulhu : RVVUnsignedBinBuiltinSet; defm vmulhsu : RVVOutOp1BuiltinSet<"vmulhsu", "csil", [["vv", "v", "vvUv"], ["vx", "v", "vvUe"]]>; +} // 12.11. Vector Integer Divide Instructions defm vdivu : RVVUnsignedBinBuiltinSet; @@ -1743,7 +1765,9 @@ defm vasubu : RVVUnsignedBinBuiltinSet; defm vasub : RVVSignedBinBuiltinSet; // 13.3. Vector Single-Width Fractional Multiply with Rounding and Saturation +let RequiredFeatures = ["FullMultiply"] in { defm vsmul : RVVSignedBinBuiltinSet; +} // 13.4. Vector Single-Width Scaling Shift Instructions defm vssrl : RVVUnsignedShiftBuiltinSet; diff --git contrib/llvm-project/clang/include/clang/CodeGen/CodeGenABITypes.h contrib/llvm-project/clang/include/clang/CodeGen/CodeGenABITypes.h index 3c745fadbe78..fda0855dc868 100644 --- contrib/llvm-project/clang/include/clang/CodeGen/CodeGenABITypes.h +++ contrib/llvm-project/clang/include/clang/CodeGen/CodeGenABITypes.h @@ -32,26 +32,18 @@ namespace llvm { class AttrBuilder; class Constant; -class DataLayout; -class Module; class Function; class FunctionType; class Type; } namespace clang { -class ASTContext; class CXXConstructorDecl; class CXXDestructorDecl; class CXXRecordDecl; class CXXMethodDecl; -class CodeGenOptions; -class CoverageSourceInfo; -class DiagnosticsEngine; -class HeaderSearchOptions; class ObjCMethodDecl; class ObjCProtocolDecl; -class PreprocessorOptions; namespace CodeGen { class CGFunctionInfo; diff --git contrib/llvm-project/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h contrib/llvm-project/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h index 8821cd70362e..c13e052149d9 100644 --- contrib/llvm-project/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h +++ contrib/llvm-project/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_CODEGEN_OBJECT_FILE_PCH_CONTAINER_OPERATIONS_H -#define LLVM_CLANG_CODEGEN_OBJECT_FILE_PCH_CONTAINER_OPERATIONS_H +#ifndef LLVM_CLANG_CODEGEN_OBJECTFILEPCHCONTAINEROPERATIONS_H +#define LLVM_CLANG_CODEGEN_OBJECTFILEPCHCONTAINEROPERATIONS_H #include "clang/Frontend/PCHContainerOperations.h" diff --git contrib/llvm-project/clang/include/clang/CodeGen/SwiftCallingConv.h contrib/llvm-project/clang/include/clang/CodeGen/SwiftCallingConv.h index b1a638a58a09..d7a0c84699ab 100644 --- contrib/llvm-project/clang/include/clang/CodeGen/SwiftCallingConv.h +++ contrib/llvm-project/clang/include/clang/CodeGen/SwiftCallingConv.h @@ -28,7 +28,6 @@ namespace llvm { } namespace clang { -class Decl; class FieldDecl; class ASTRecordLayout; diff --git contrib/llvm-project/clang/include/clang/Driver/Options.td contrib/llvm-project/clang/include/clang/Driver/Options.td index dc8bd831f2a2..b3de12e8c7b5 100644 --- contrib/llvm-project/clang/include/clang/Driver/Options.td +++ contrib/llvm-project/clang/include/clang/Driver/Options.td @@ -1076,8 +1076,12 @@ def emit_interface_stubs : Flag<["-"], "emit-interface-stubs">, Flags<[CC1Option def emit_merged_ifs : Flag<["-"], "emit-merged-ifs">, Flags<[CC1Option]>, Group<Action_Group>, HelpText<"Generate Interface Stub Files, emit merged text not binary.">; +def end_no_unused_arguments : Flag<["--"], "end-no-unused-arguments">, Flags<[CoreOption]>, + HelpText<"Start emitting warnings for unused driver arguments">; def interface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">, Flags<[CC1Option]>; def exported__symbols__list : Separate<["-"], "exported_symbols_list">; +def extract_api : Flag<["-"], "extract-api">, Flags<[CC1Option]>, Group<Action_Group>, + HelpText<"Extract API information">; def e : JoinedOrSeparate<["-"], "e">, Flags<[LinkerInput]>, Group<Link_Group>; def fmax_tokens_EQ : Joined<["-"], "fmax-tokens=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Max total number of preprocessed tokens for -Wmax-tokens.">, @@ -1667,7 +1671,13 @@ def sanitize_address_destructor_EQ NormalizedValuesScope<"llvm::AsanDtorKind">, NormalizedValues<["None", "Global"]>, MarshallingInfoEnum<CodeGenOpts<"SanitizeAddressDtor">, "Global">; -// Note: This flag was introduced when it was necessary to distinguish between +defm sanitize_memory_param_retval + : BoolFOption<"sanitize-memory-param-retval", + CodeGenOpts<"SanitizeMemoryParamRetval">, + DefaultFalse, + PosFlag<SetTrue, [CC1Option], "Enable">, NegFlag<SetFalse, [], "Disable">, + BothFlags<[], " detection of uninitialized parameters and return values">>; +//// Note: This flag was introduced when it was necessary to distinguish between // ABI for correct codegen. This is no longer needed, but the flag is // not removed since targeting either ABI will behave the same. // This way we cause no disturbance to existing scripts & code, and if we @@ -1919,6 +1929,8 @@ def fcf_protection_EQ : Joined<["-"], "fcf-protection=">, Flags<[CoreOption, CC1 def fcf_protection : Flag<["-"], "fcf-protection">, Group<f_Group>, Flags<[CoreOption, CC1Option]>, Alias<fcf_protection_EQ>, AliasArgs<["full"]>, HelpText<"Enable cf-protection in 'full' mode">; +def mibt_seal : Flag<["-"], "mibt-seal">, Group<m_Group>, Flags<[CoreOption, CC1Option]>, + HelpText<"Optimize fcf-protection=branch/full (requires LTO).">; defm xray_instrument : BoolFOption<"xray-instrument", LangOpts<"XRayInstrument">, DefaultFalse, @@ -2490,6 +2502,9 @@ defm pascal_strings : BoolFOption<"pascal-strings", def fpatchable_function_entry_EQ : Joined<["-"], "fpatchable-function-entry=">, Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<N,M>">, HelpText<"Generate M NOPs before function entry and N-M NOPs after function entry">, MarshallingInfoInt<CodeGenOpts<"PatchableFunctionEntryCount">>; +def fms_hotpatch : Flag<["-"], "fms-hotpatch">, Group<f_Group>, Flags<[CC1Option, CoreOption]>, + HelpText<"Ensure that all functions can be hotpatched at runtime">, + MarshallingInfoFlag<CodeGenOpts<"HotPatch">>; def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Override the default ABI to return all structs on the stack">; def fpch_preprocess : Flag<["-"], "fpch-preprocess">, Group<f_Group>; @@ -3617,6 +3632,7 @@ def mcheck_zero_division : Flag<["-"], "mcheck-zero-division">, Group<m_mips_Features_Group>; def mno_check_zero_division : Flag<["-"], "mno-check-zero-division">, Group<m_mips_Features_Group>; +def mfix4300 : Flag<["-"], "mfix4300">, Group<m_mips_Features_Group>; def mcompact_branches_EQ : Joined<["-"], "mcompact-branches=">, Group<m_mips_Features_Group>; def mbranch_likely : Flag<["-"], "mbranch-likely">, Group<m_Group>, @@ -3912,6 +3928,8 @@ def shared : Flag<["-", "--"], "shared">, Group<Link_Group>; def single__module : Flag<["-"], "single_module">; def specs_EQ : Joined<["-", "--"], "specs=">, Group<Link_Group>; def specs : Separate<["-", "--"], "specs">, Flags<[Unsupported]>; +def start_no_unused_arguments : Flag<["--"], "start-no-unused-arguments">, Flags<[CoreOption]>, + HelpText<"Don't emit warnings about unused arguments for the following arguments">; def static_libgcc : Flag<["-"], "static-libgcc">; def static_libstdcxx : Flag<["-"], "static-libstdc++">; def static : Flag<["-", "--"], "static">, Group<Link_Group>, Flags<[NoArgumentUnused]>; @@ -4956,8 +4974,8 @@ def record_command_line : Separate<["-"], "record-command-line">, HelpText<"The string to embed in the .LLVM.command.line section.">, MarshallingInfoString<CodeGenOpts<"RecordCommandLine">>; def compress_debug_sections_EQ : Joined<["-", "--"], "compress-debug-sections=">, - HelpText<"DWARF debug sections compression type">, Values<"none,zlib,zlib-gnu">, - NormalizedValuesScope<"llvm::DebugCompressionType">, NormalizedValues<["None", "Z", "GNU"]>, + HelpText<"DWARF debug sections compression type">, Values<"none,zlib">, + NormalizedValuesScope<"llvm::DebugCompressionType">, NormalizedValues<["None", "Z"]>, MarshallingInfoEnum<CodeGenOpts<"CompressDebugSections">, "None">; def compress_debug_sections : Flag<["-", "--"], "compress-debug-sections">, Alias<compress_debug_sections_EQ>, AliasArgs<["zlib"]>; @@ -5385,9 +5403,9 @@ defm clear_ast_before_backend : BoolOption<"", PosFlag<SetTrue, [], "Clear">, NegFlag<SetFalse, [], "Don't clear">, BothFlags<[], " the Clang AST before running backend code generation">>; -def enable_noundef_analysis : Flag<["-"], "enable-noundef-analysis">, Group<f_Group>, - HelpText<"Enable analyzing function argument and return types for mandatory definedness">, - MarshallingInfoFlag<CodeGenOpts<"EnableNoundefAttrs">>; +def disable_noundef_analysis : Flag<["-"], "disable-noundef-analysis">, Group<f_Group>, + HelpText<"Disable analyzing function argument and return types for mandatory definedness">, + MarshallingInfoFlag<CodeGenOpts<"DisableNoundefAttrs">>; def discard_value_names : Flag<["-"], "discard-value-names">, HelpText<"Discard value names in LLVM IR">, MarshallingInfoFlag<CodeGenOpts<"DiscardValueNames">>; @@ -6113,6 +6131,8 @@ def _SLASH_Gw_ : CLFlag<"Gw-">, def _SLASH_help : CLFlag<"help">, Alias<help>, HelpText<"Display available options">; def _SLASH_HELP : CLFlag<"HELP">, Alias<help>; +def _SLASH_hotpatch : CLFlag<"hotpatch">, Alias<fms_hotpatch>, + HelpText<"Create hotpatchable image">; def _SLASH_I : CLJoinedOrSeparate<"I">, HelpText<"Add directory to include search path">, MetaVarName<"<dir>">, Alias<I>; @@ -6469,7 +6489,6 @@ def _SLASH_headerUnit : CLJoinedOrSeparate<"headerUnit">; def _SLASH_headerUnitAngle : CLJoinedOrSeparate<"headerUnit:angle">; def _SLASH_headerUnitQuote : CLJoinedOrSeparate<"headerUnit:quote">; def _SLASH_homeparams : CLFlag<"homeparams">; -def _SLASH_hotpatch : CLFlag<"hotpatch">; def _SLASH_kernel : CLFlag<"kernel">; def _SLASH_LN : CLFlag<"LN">; def _SLASH_MP : CLJoined<"MP">; diff --git contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h index 84bb324775d1..d288b0151c9f 100644 --- contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h +++ contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h @@ -33,6 +33,7 @@ class SanitizerArgs { int CoverageFeatures = 0; int MsanTrackOrigins = 0; bool MsanUseAfterDtor = true; + bool MsanParamRetval = false; bool CfiCrossDso = false; bool CfiICallGeneralizePointers = false; bool CfiCanonicalJumpTables = false; diff --git contrib/llvm-project/clang/include/clang/Driver/ToolChain.h contrib/llvm-project/clang/include/clang/Driver/ToolChain.h index 4afc9bf36b5f..329833bb13be 100644 --- contrib/llvm-project/clang/include/clang/Driver/ToolChain.h +++ contrib/llvm-project/clang/include/clang/Driver/ToolChain.h @@ -409,6 +409,9 @@ public: /// Check whether to enable x86 relax relocations by default. virtual bool useRelaxRelocations() const; + /// Check whether use IEEE binary128 as long double format by default. + bool defaultToIEEELongDouble() const; + /// GetDefaultStackProtectorLevel - Get the default stack protector level for /// this tool chain. virtual LangOptions::StackProtectorMode @@ -452,11 +455,11 @@ public: StringRef Component, FileType Type = ToolChain::FT_Static) const; - // Returns target specific runtime path if it exists. - virtual std::string getRuntimePath() const; + // Returns target specific runtime paths. + path_list getRuntimePaths() const; - // Returns target specific standard library path if it exists. - virtual std::string getStdlibPath() const; + // Returns target specific standard library paths. + path_list getStdlibPaths() const; // Returns <ResourceDir>/lib/<OSName>/<arch>. This is used by runtimes (such // as OpenMP) to find arch-specific libraries. @@ -510,7 +513,7 @@ public: // Return the DWARF version to emit, in the absence of arguments // to the contrary. - virtual unsigned GetDefaultDwarfVersion() const { return 4; } + virtual unsigned GetDefaultDwarfVersion() const { return 5; } // Some toolchains may have different restrictions on the DWARF version and // may need to adjust it. E.g. NVPTX may need to enforce DWARF2 even when host diff --git contrib/llvm-project/clang/include/clang/Driver/Types.def contrib/llvm-project/clang/include/clang/Driver/Types.def index 997eea445c22..7adf59ca5c99 100644 --- contrib/llvm-project/clang/include/clang/Driver/Types.def +++ contrib/llvm-project/clang/include/clang/Driver/Types.def @@ -100,4 +100,5 @@ TYPE("dSYM", dSYM, INVALID, "dSYM", phases TYPE("dependencies", Dependencies, INVALID, "d", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("cuda-fatbin", CUDA_FATBIN, INVALID, "fatbin", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("hip-fatbin", HIP_FATBIN, INVALID, "hipfb", phases::Compile, phases::Backend, phases::Assemble, phases::Link) +TYPE("api-information", API_INFO, INVALID, "json", phases::Compile) TYPE("none", Nothing, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link) diff --git contrib/llvm-project/clang/include/clang/Driver/Util.h contrib/llvm-project/clang/include/clang/Driver/Util.h index 6788420912a1..92d3d40433a3 100644 --- contrib/llvm-project/clang/include/clang/Driver/Util.h +++ contrib/llvm-project/clang/include/clang/Driver/Util.h @@ -13,7 +13,6 @@ #include "llvm/ADT/DenseMap.h" namespace clang { -class DiagnosticsEngine; namespace driver { class Action; diff --git contrib/llvm-project/clang/include/clang/Format/Format.h contrib/llvm-project/clang/include/clang/Format/Format.h index 0f97e80d425e..326e85305c8e 100755 --- contrib/llvm-project/clang/include/clang/Format/Format.h +++ contrib/llvm-project/clang/include/clang/Format/Format.h @@ -29,11 +29,6 @@ class FileSystem; } // namespace llvm namespace clang { - -class Lexer; -class SourceManager; -class DiagnosticConsumer; - namespace format { enum class ParseError { @@ -87,6 +82,19 @@ struct FormatStyle { /// argument1, argument2); /// \endcode BAS_AlwaysBreak, + /// Always break after an open bracket, if the parameters don't fit + /// on a single line. Closing brackets will be placed on a new line. + /// E.g.: + /// \code + /// someLongFunction( + /// argument1, argument2 + /// ) + /// \endcode + /// + /// \warning + /// Note: This currently only applies to parentheses. + /// \endwarning + BAS_BlockIndent, }; /// If ``true``, horizontally aligns arguments after an open bracket. @@ -2704,7 +2712,7 @@ struct FormatStyle { /// readability to have the signature indented two levels and to use /// ``OuterScope``. The KJ style guide requires ``OuterScope``. /// `KJ style guide - /// <https://github.com/capnproto/capnproto/blob/master/kjdoc/style-guide.md>`_ + /// <https://github.com/capnproto/capnproto/blob/master/style-guide.md>`_ /// \version 13 LambdaBodyIndentationKind LambdaBodyIndentation; @@ -2887,6 +2895,10 @@ struct FormatStyle { /// \version 3.7 unsigned PenaltyBreakFirstLessLess; + /// The penalty for breaking after ``(``. + /// \version 14 + unsigned PenaltyBreakOpenParenthesis; + /// The penalty for each line break introduced inside a string literal. /// \version 3.7 unsigned PenaltyBreakString; @@ -3050,6 +3062,118 @@ struct FormatStyle { bool ReflowComments; // clang-format on + /// Remove optional braces of control statements (``if``, ``else``, ``for``, + /// and ``while``) in C++ according to the LLVM coding style. + /// \warning + /// This option will be renamed and expanded to support other styles. + /// \endwarning + /// \warning + /// Setting this option to `true` could lead to incorrect code formatting due + /// to clang-format's lack of complete semantic information. As such, extra + /// care should be taken to review code changes made by this option. + /// \endwarning + /// \code + /// false: true: + /// + /// if (isa<FunctionDecl>(D)) { vs. if (isa<FunctionDecl>(D)) + /// handleFunctionDecl(D); handleFunctionDecl(D); + /// } else if (isa<VarDecl>(D)) { else if (isa<VarDecl>(D)) + /// handleVarDecl(D); handleVarDecl(D); + /// } + /// + /// if (isa<VarDecl>(D)) { vs. if (isa<VarDecl>(D)) { + /// for (auto *A : D.attrs()) { for (auto *A : D.attrs()) + /// if (shouldProcessAttr(A)) { if (shouldProcessAttr(A)) + /// handleAttr(A); handleAttr(A); + /// } } + /// } + /// } + /// + /// if (isa<FunctionDecl>(D)) { vs. if (isa<FunctionDecl>(D)) + /// for (auto *A : D.attrs()) { for (auto *A : D.attrs()) + /// handleAttr(A); handleAttr(A); + /// } + /// } + /// + /// if (auto *D = (T)(D)) { vs. if (auto *D = (T)(D)) { + /// if (shouldProcess(D)) { if (shouldProcess(D)) + /// handleVarDecl(D); handleVarDecl(D); + /// } else { else + /// markAsIgnored(D); markAsIgnored(D); + /// } } + /// } + /// + /// if (a) { vs. if (a) + /// b(); b(); + /// } else { else if (c) + /// if (c) { d(); + /// d(); else + /// } else { e(); + /// e(); + /// } + /// } + /// \endcode + /// \version 14 + bool RemoveBracesLLVM; + + /// \brief The style if definition blocks should be separated. + enum SeparateDefinitionStyle { + /// Leave definition blocks as they are. + SDS_Leave, + /// Insert an empty line between definition blocks. + SDS_Always, + /// Remove any empty line between definition blocks. + SDS_Never + }; + + /// Specifies the use of empty lines to separate definition blocks, including + /// classes, structs, enums, and functions. + /// \code + /// Never v.s. Always + /// #include <cstring> #include <cstring> + /// struct Foo { + /// int a, b, c; struct Foo { + /// }; int a, b, c; + /// namespace Ns { }; + /// class Bar { + /// public: namespace Ns { + /// struct Foobar { class Bar { + /// int a; public: + /// int b; struct Foobar { + /// }; int a; + /// private: int b; + /// int t; }; + /// int method1() { + /// // ... private: + /// } int t; + /// enum List { + /// ITEM1, int method1() { + /// ITEM2 // ... + /// }; } + /// template<typename T> + /// int method2(T x) { enum List { + /// // ... ITEM1, + /// } ITEM2 + /// int i, j, k; }; + /// int method3(int par) { + /// // ... template<typename T> + /// } int method2(T x) { + /// }; // ... + /// class C {}; } + /// } + /// int i, j, k; + /// + /// int method3(int par) { + /// // ... + /// } + /// }; + /// + /// class C {}; + /// } + /// \endcode + /// \version 14 + SeparateDefinitionStyle SeparateDefinitionBlocks; + /// The maximal number of unwrapped lines that a short namespace spans. /// Defaults to 1. /// @@ -3368,6 +3492,14 @@ struct FormatStyle { /// <conditional-body> <conditional-body> /// \endcode bool AfterIfMacros; + /// If ``true``, put a space between operator overloading and opening + /// parentheses. + /// \code + /// true: false: + /// void operator++ (int a); vs. void operator++(int a); + /// object.operator++ (10); object.operator++(10); + /// \endcode + bool AfterOverloadedOperator; /// If ``true``, put a space before opening parentheses only if the /// parentheses are not empty. /// \code @@ -3381,7 +3513,7 @@ struct FormatStyle { : AfterControlStatements(false), AfterForeachMacros(false), AfterFunctionDeclarationName(false), AfterFunctionDefinitionName(false), AfterIfMacros(false), - BeforeNonEmptyParentheses(false) {} + AfterOverloadedOperator(false), BeforeNonEmptyParentheses(false) {} bool operator==(const SpaceBeforeParensCustom &Other) const { return AfterControlStatements == Other.AfterControlStatements && @@ -3390,6 +3522,7 @@ struct FormatStyle { Other.AfterFunctionDeclarationName && AfterFunctionDefinitionName == Other.AfterFunctionDefinitionName && AfterIfMacros == Other.AfterIfMacros && + AfterOverloadedOperator == Other.AfterOverloadedOperator && BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses; } }; @@ -3781,6 +3914,7 @@ struct FormatStyle { R.PenaltyBreakBeforeFirstCallParameter && PenaltyBreakComment == R.PenaltyBreakComment && PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess && + PenaltyBreakOpenParenthesis == R.PenaltyBreakOpenParenthesis && PenaltyBreakString == R.PenaltyBreakString && PenaltyExcessCharacter == R.PenaltyExcessCharacter && PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine && @@ -3791,6 +3925,8 @@ struct FormatStyle { QualifierOrder == R.QualifierOrder && RawStringFormats == R.RawStringFormats && ReferenceAlignment == R.ReferenceAlignment && + RemoveBracesLLVM == R.RemoveBracesLLVM && + SeparateDefinitionBlocks == R.SeparateDefinitionBlocks && ShortNamespaceLines == R.ShortNamespaceLines && SortIncludes == R.SortIncludes && SortJavaStaticImport == R.SortJavaStaticImport && @@ -3888,7 +4024,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language); FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language); /// Returns a format style complying with Mozilla's style guide: -/// https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style. +/// https://firefox-source-docs.mozilla.org/code-quality/coding-style/index.html. FormatStyle getMozillaStyle(); /// Returns a format style complying with Webkit's style guide: @@ -4028,6 +4164,17 @@ tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, ArrayRef<tooling::Range> Ranges, StringRef FileName = "<stdin>"); +/// Inserts or removes empty lines separating definition blocks including +/// classes, structs, functions, namespaces, and enums in the given \p Ranges in +/// \p Code. +/// +/// Returns the ``Replacements`` that inserts or removes empty lines separating +/// definition blocks in all \p Ranges in \p Code. +tooling::Replacements separateDefinitionBlocks(const FormatStyle &Style, + StringRef Code, + ArrayRef<tooling::Range> Ranges, + StringRef FileName = "<stdin>"); + /// Sort consecutive using declarations in the given \p Ranges in /// \p Code. /// @@ -4066,6 +4213,8 @@ extern const char *DefaultFallbackStyle; /// * "file" - Load style configuration from a file called ``.clang-format`` /// located in one of the parent directories of ``FileName`` or the current /// directory if ``FileName`` is empty. +/// * "file:<format_file_path>" to explicitly specify the configuration file to +/// use. /// /// \param[in] StyleName Style name to interpret according to the description /// above. diff --git contrib/llvm-project/clang/include/clang/Frontend/ASTConsumers.h contrib/llvm-project/clang/include/clang/Frontend/ASTConsumers.h index 98cfc7cadc0d..0e068bf5cccb 100644 --- contrib/llvm-project/clang/include/clang/Frontend/ASTConsumers.h +++ contrib/llvm-project/clang/include/clang/Frontend/ASTConsumers.h @@ -20,12 +20,6 @@ namespace clang { class ASTConsumer; -class CodeGenOptions; -class DiagnosticsEngine; -class FileManager; -class LangOptions; -class Preprocessor; -class TargetOptions; // AST pretty-printer: prints out the AST in a format that is close to the // original C code. The output is intended to be in a format such that diff --git contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h index 74e152ea5952..577daad86b20 100644 --- contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h +++ contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h @@ -41,8 +41,6 @@ class ASTReader; class CodeCompleteConsumer; class DiagnosticsEngine; class DiagnosticConsumer; -class ExternalASTSource; -class FileEntry; class FileManager; class FrontendAction; class InMemoryModuleCache; diff --git contrib/llvm-project/clang/include/clang/Frontend/FrontendActions.h contrib/llvm-project/clang/include/clang/Frontend/FrontendActions.h index 545a7e842c4f..8eceb81723d2 100644 --- contrib/llvm-project/clang/include/clang/Frontend/FrontendActions.h +++ contrib/llvm-project/clang/include/clang/Frontend/FrontendActions.h @@ -10,14 +10,12 @@ #define LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H #include "clang/Frontend/FrontendAction.h" +#include <memory> #include <string> #include <vector> namespace clang { -class Module; -class FileEntry; - //===----------------------------------------------------------------------===// // Custom Consumer Actions //===----------------------------------------------------------------------===// @@ -273,6 +271,12 @@ protected: bool usesPreprocessorOnly() const override { return true; } }; +class ExtractAPIAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; +}; + //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// diff --git contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h index 1d9d89a28c6c..7ce8076a3ee4 100644 --- contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h +++ contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h @@ -75,6 +75,9 @@ enum ActionKind { /// Emit a .o file. EmitObj, + // Extract API information + ExtractAPI, + /// Parse and apply any fixits to the source. FixIt, diff --git contrib/llvm-project/clang/include/clang/Frontend/PCHContainerOperations.h contrib/llvm-project/clang/include/clang/Frontend/PCHContainerOperations.h index fa977a63f32e..098d32ec3869 100644 --- contrib/llvm-project/clang/include/clang/Frontend/PCHContainerOperations.h +++ contrib/llvm-project/clang/include/clang/Frontend/PCHContainerOperations.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H -#define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H +#ifndef LLVM_CLANG_FRONTEND_PCHCONTAINEROPERATIONS_H +#define LLVM_CLANG_FRONTEND_PCHCONTAINEROPERATIONS_H #include "clang/Serialization/PCHContainerOperations.h" diff --git contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h index dacbffef0b12..628736f34091 100644 --- contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h +++ contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_FRONTEND_PRECOMPILED_PREAMBLE_H -#define LLVM_CLANG_FRONTEND_PRECOMPILED_PREAMBLE_H +#ifndef LLVM_CLANG_FRONTEND_PRECOMPILEDPREAMBLE_H +#define LLVM_CLANG_FRONTEND_PRECOMPILEDPREAMBLE_H #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" diff --git contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h index 58954dc6bafa..5586ef65e393 100644 --- contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h +++ contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h @@ -19,7 +19,6 @@ class raw_ostream; namespace clang { class DiagnosticConsumer; -class DiagnosticsEngine; class DiagnosticOptions; namespace serialized_diags { diff --git contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnostics.h contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnostics.h index 4e67fd13ac5b..6464693c1482 100644 --- contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnostics.h +++ contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnostics.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_ -#define LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_ +#ifndef LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICS_H +#define LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICS_H #include "llvm/Bitstream/BitCodes.h" diff --git contrib/llvm-project/clang/include/clang/Frontend/Utils.h contrib/llvm-project/clang/include/clang/Frontend/Utils.h index da2d79af2eba..a05584bfe551 100644 --- contrib/llvm-project/clang/include/clang/Frontend/Utils.h +++ contrib/llvm-project/clang/include/clang/Frontend/Utils.h @@ -32,12 +32,6 @@ #include <utility> #include <vector> -namespace llvm { - -class Triple; - -} // namespace llvm - namespace clang { class ASTReader; @@ -46,20 +40,11 @@ class CompilerInvocation; class DiagnosticsEngine; class ExternalSemaSource; class FrontendOptions; -class HeaderSearch; -class HeaderSearchOptions; -class LangOptions; class PCHContainerReader; class Preprocessor; class PreprocessorOptions; class PreprocessorOutputOptions; -/// Apply the header search options to get given HeaderSearch object. -void ApplyHeaderSearchOptions(HeaderSearch &HS, - const HeaderSearchOptions &HSOpts, - const LangOptions &Lang, - const llvm::Triple &triple); - /// InitializePreprocessor - Initialize the preprocessor getting it and the /// environment ready to process a single file. void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, diff --git contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h index 20cf8fbdad96..eb66e725000c 100644 --- contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h +++ contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_INDEX_SerializablePathCollection_H -#define LLVM_CLANG_INDEX_SerializablePathCollection_H +#ifndef LLVM_CLANG_INDEXSERIALIZATION_SERIALIZABLEPATHCOLLECTION_H +#define LLVM_CLANG_INDEXSERIALIZATION_SERIALIZABLEPATHCOLLECTION_H #include "clang/Basic/FileManager.h" #include "llvm/ADT/APInt.h" @@ -126,4 +126,4 @@ private: } // namespace index } // namespace clang -#endif // LLVM_CLANG_INDEX_SerializablePathCollection_H +#endif // LLVM_CLANG_INDEXSERIALIZATION_SERIALIZABLEPATHCOLLECTION_H diff --git contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h index 2dc0fd5963a2..721a649deb43 100644 --- contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h +++ contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h @@ -28,13 +28,11 @@ namespace llvm { namespace orc { class ThreadSafeContext; } -class Module; } // namespace llvm namespace clang { class CompilerInstance; -class DeclGroupRef; class IncrementalExecutor; class IncrementalParser; diff --git contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h index 121ca893e314..56025c8a3ed5 100644 --- contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h +++ contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h @@ -14,8 +14,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LEX_DEPENDENCY_DIRECTIVES_SOURCE_MINIMIZER_H -#define LLVM_CLANG_LEX_DEPENDENCY_DIRECTIVES_SOURCE_MINIMIZER_H +#ifndef LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSOURCEMINIMIZER_H +#define LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSOURCEMINIMIZER_H #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" @@ -112,4 +112,4 @@ bool minimizeSourceToDependencyDirectives( } // end namespace clang -#endif // LLVM_CLANG_LEX_DEPENDENCY_DIRECTIVES_SOURCE_MINIMIZER_H +#endif // LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSOURCEMINIMIZER_H diff --git contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h index b3445703f782..74768717470b 100644 --- contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h +++ contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h @@ -34,6 +34,12 @@ #include <utility> #include <vector> +namespace llvm { + +class Triple; + +} // namespace llvm + namespace clang { class DiagnosticsEngine; @@ -51,6 +57,8 @@ class TargetInfo; /// The preprocessor keeps track of this information for each /// file that is \#included. struct HeaderFileInfo { + // TODO: Whether the file was imported is not a property of the file itself. + // It's a preprocessor state, move it there. /// True if this is a \#import'd file. unsigned isImport : 1; @@ -89,9 +97,6 @@ struct HeaderFileInfo { /// Whether this file has been looked up as a header. unsigned IsValid : 1; - /// The number of times the file has been included already. - unsigned short NumIncludes = 0; - /// The ID number of the controlling macro. /// /// This ID number will be non-zero when there is a controlling @@ -281,26 +286,15 @@ public: /// Interface for setting the file search paths. void SetSearchPaths(std::vector<DirectoryLookup> dirs, unsigned angledDirIdx, unsigned systemDirIdx, bool noCurDirSearch, - llvm::DenseMap<unsigned, unsigned> searchDirToHSEntry) { - assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() && - "Directory indices are unordered"); - SearchDirs = std::move(dirs); - SearchDirsUsage.assign(SearchDirs.size(), false); - AngledDirIdx = angledDirIdx; - SystemDirIdx = systemDirIdx; - NoCurDirSearch = noCurDirSearch; - SearchDirToHSEntry = std::move(searchDirToHSEntry); - //LookupFileCache.clear(); - } + llvm::DenseMap<unsigned, unsigned> searchDirToHSEntry); /// Add an additional search path. - void AddSearchPath(const DirectoryLookup &dir, bool isAngled) { - unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx; - SearchDirs.insert(SearchDirs.begin() + idx, dir); - SearchDirsUsage.insert(SearchDirsUsage.begin() + idx, false); - if (!isAngled) - AngledDirIdx++; - SystemDirIdx++; + void AddSearchPath(const DirectoryLookup &dir, bool isAngled); + + /// Add an additional system search path. + void AddSystemSearchPath(const DirectoryLookup &dir) { + SearchDirs.push_back(dir); + SearchDirsUsage.push_back(false); } /// Set the list of system header prefixes. @@ -413,7 +407,7 @@ public: /// found. Optional<FileEntryRef> LookupFile( StringRef Filename, SourceLocation IncludeLoc, bool isAngled, - const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, + const DirectoryLookup *FromDir, const DirectoryLookup **CurDir, ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, @@ -474,12 +468,6 @@ public: ModuleMap::ModuleHeaderRole Role, bool isCompilingModuleHeader); - /// Increment the count for the number of times the specified - /// FileEntry has been entered. - void IncrementIncludeCount(const FileEntry *File) { - ++getFileInfo(File).NumIncludes; - } - /// Mark the specified file as having a controlling macro. /// /// This is used by the multiple-include optimization to eliminate @@ -856,6 +844,12 @@ private: bool IsSystem, bool IsFramework); }; +/// Apply the header search options to get given HeaderSearch object. +void ApplyHeaderSearchOptions(HeaderSearch &HS, + const HeaderSearchOptions &HSOpts, + const LangOptions &Lang, + const llvm::Triple &triple); + } // namespace clang #endif // LLVM_CLANG_LEX_HEADERSEARCH_H diff --git contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h index ea96bb12bec6..e567f6391531 100644 --- contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h +++ contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h @@ -450,6 +450,8 @@ public: ElseLoc(ElseLoc) {} }; + using IncludedFilesSet = llvm::DenseSet<const FileEntry *>; + private: friend class ASTReader; friend class MacroArgs; @@ -765,6 +767,9 @@ private: /// in a submodule. SubmoduleState *CurSubmoduleState; + /// The files that have been included. + IncludedFilesSet IncludedFiles; + /// The set of known macros exported from modules. llvm::FoldingSet<ModuleMacro> ModuleMacros; @@ -1224,6 +1229,22 @@ public: /// \} + /// Mark the file as included. + /// Returns true if this is the first time the file was included. + bool markIncluded(const FileEntry *File) { + HeaderInfo.getFileInfo(File); + return IncludedFiles.insert(File).second; + } + + /// Return true if this header has already been included. + bool alreadyIncluded(const FileEntry *File) const { + return IncludedFiles.count(File); + } + + /// Get the set of included files. + IncludedFilesSet &getIncludedFiles() { return IncludedFiles; } + const IncludedFilesSet &getIncludedFiles() const { return IncludedFiles; } + /// Return the name of the macro defined before \p Loc that has /// spelling \p Tokens. If there are multiple macros with same spelling, /// return the last one defined. @@ -2051,7 +2072,7 @@ public: Optional<FileEntryRef> LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const FileEntry *FromFile, - const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath, + const DirectoryLookup **CurDir, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache = false); @@ -2300,7 +2321,7 @@ private: }; Optional<FileEntryRef> LookupHeaderIncludeOrImport( - const DirectoryLookup *&CurDir, StringRef &Filename, + const DirectoryLookup **CurDir, StringRef &Filename, SourceLocation FilenameLoc, CharSourceRange FilenameRange, const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl, bool &IsMapped, const DirectoryLookup *LookupFrom, diff --git contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h index 1a0d5ed57b28..49687cb5cc85 100644 --- contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h +++ contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LEX_PREPROCESSOR_EXCLUDED_COND_DIRECTIVE_SKIP_MAPPING_H -#define LLVM_CLANG_LEX_PREPROCESSOR_EXCLUDED_COND_DIRECTIVE_SKIP_MAPPING_H +#ifndef LLVM_CLANG_LEX_PREPROCESSOREXCLUDEDCONDITIONALDIRECTIVESKIPMAPPING_H +#define LLVM_CLANG_LEX_PREPROCESSOREXCLUDEDCONDITIONALDIRECTIVESKIPMAPPING_H #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" @@ -27,4 +27,4 @@ using ExcludedPreprocessorDirectiveSkipMapping = } // end namespace clang -#endif // LLVM_CLANG_LEX_PREPROCESSOR_EXCLUDED_COND_DIRECTIVE_SKIP_MAPPING_H +#endif // LLVM_CLANG_LEX_PREPROCESSOREXCLUDEDCONDITIONALDIRECTIVESKIPMAPPING_H diff --git contrib/llvm-project/clang/include/clang/Parse/Parser.h contrib/llvm-project/clang/include/clang/Parse/Parser.h index 741a484390b2..74010ca66f99 100644 --- contrib/llvm-project/clang/include/clang/Parse/Parser.h +++ contrib/llvm-project/clang/include/clang/Parse/Parser.h @@ -1475,8 +1475,7 @@ private: /// information that has been parsed prior to parsing declaration /// specifiers. struct ParsedTemplateInfo { - ParsedTemplateInfo() - : Kind(NonTemplate), TemplateParams(nullptr), TemplateLoc() { } + ParsedTemplateInfo() : Kind(NonTemplate), TemplateParams(nullptr) {} ParsedTemplateInfo(TemplateParameterLists *TemplateParams, bool isSpecialization, @@ -1976,6 +1975,7 @@ private: Sema::ConditionResult ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc, Sema::ConditionKind CK, + bool MissingOK, ForRangeInfo *FRI = nullptr, bool EnterForConditionScope = false); DeclGroupPtrTy @@ -2080,8 +2080,8 @@ private: bool ParseParenExprOrCondition(StmtResult *InitStmt, Sema::ConditionResult &CondResult, SourceLocation Loc, Sema::ConditionKind CK, - SourceLocation *LParenLoc = nullptr, - SourceLocation *RParenLoc = nullptr); + bool MissingOK, SourceLocation *LParenLoc, + SourceLocation *RParenLoc); StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc); StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc); StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc); @@ -3315,6 +3315,11 @@ private: /// nullptr. /// OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind, bool ParseOnly); + /// Parses indirect clause + /// \param ParseOnly true to skip the clause's semantic actions and return + // false; + bool ParseOpenMPIndirectClause(Sema::DeclareTargetContextInfo &DTCI, + bool ParseOnly); /// Parses clause with a single expression and an additional argument /// of a kind \a Kind. /// @@ -3454,7 +3459,8 @@ private: bool ParseTemplateIdAfterTemplateName(bool ConsumeLastToken, SourceLocation &LAngleLoc, TemplateArgList &TemplateArgs, - SourceLocation &RAngleLoc); + SourceLocation &RAngleLoc, + TemplateTy NameHint = nullptr); bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, CXXScopeSpec &SS, @@ -3464,7 +3470,8 @@ private: bool TypeConstraint = false); void AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS, bool IsClassName = false); - bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs); + bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs, + TemplateTy Template, SourceLocation OpenLoc); ParsedTemplateArgument ParseTemplateTemplateArgument(); ParsedTemplateArgument ParseTemplateArgument(); Decl *ParseExplicitInstantiation(DeclaratorContext Context, diff --git contrib/llvm-project/clang/include/clang/Parse/RAIIObjectsForParser.h contrib/llvm-project/clang/include/clang/Parse/RAIIObjectsForParser.h index bc1754614ad9..8e6e03685c50 100644 --- contrib/llvm-project/clang/include/clang/Parse/RAIIObjectsForParser.h +++ contrib/llvm-project/clang/include/clang/Parse/RAIIObjectsForParser.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LIB_PARSE_RAIIOBJECTSFORPARSER_H -#define LLVM_CLANG_LIB_PARSE_RAIIOBJECTSFORPARSER_H +#ifndef LLVM_CLANG_PARSE_RAIIOBJECTSFORPARSER_H +#define LLVM_CLANG_PARSE_RAIIOBJECTSFORPARSER_H #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" diff --git contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h index 49b69c585ff7..13a88bb9f896 100644 --- contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h +++ contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h @@ -18,10 +18,8 @@ namespace clang { -class BlockExpr; class Decl; class FunctionDecl; -class ObjCMethodDecl; class QualType; class Sema; namespace sema { diff --git contrib/llvm-project/clang/include/clang/Sema/CleanupInfo.h contrib/llvm-project/clang/include/clang/Sema/CleanupInfo.h index ea9df49f77e1..45d16fea93e0 100644 --- contrib/llvm-project/clang/include/clang/Sema/CleanupInfo.h +++ contrib/llvm-project/clang/include/clang/Sema/CleanupInfo.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_CLEANUP_INFO_H -#define LLVM_CLANG_SEMA_CLEANUP_INFO_H +#ifndef LLVM_CLANG_SEMA_CLEANUPINFO_H +#define LLVM_CLANG_SEMA_CLEANUPINFO_H namespace clang { diff --git contrib/llvm-project/clang/include/clang/Sema/CodeCompleteConsumer.h contrib/llvm-project/clang/include/clang/Sema/CodeCompleteConsumer.h index 6b37e3c50dba..41c495882b27 100644 --- contrib/llvm-project/clang/include/clang/Sema/CodeCompleteConsumer.h +++ contrib/llvm-project/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -1009,12 +1009,18 @@ public: /// The candidate is a function declaration. CK_Function, - /// The candidate is a function template. + /// The candidate is a function template, arguments are being completed. CK_FunctionTemplate, /// The "candidate" is actually a variable, expression, or block /// for which we only have a function prototype. - CK_FunctionType + CK_FunctionType, + + /// The candidate is a template, template arguments are being completed. + CK_Template, + + /// The candidate is aggregate initialization of a record type. + CK_Aggregate, }; private: @@ -1033,17 +1039,39 @@ public: /// The function type that describes the entity being called, /// when Kind == CK_FunctionType. const FunctionType *Type; + + /// The template overload candidate, available when + /// Kind == CK_Template. + const TemplateDecl *Template; + + /// The class being aggregate-initialized, + /// when Kind == CK_Aggregate + const RecordDecl *AggregateType; }; public: OverloadCandidate(FunctionDecl *Function) - : Kind(CK_Function), Function(Function) {} + : Kind(CK_Function), Function(Function) { + assert(Function != nullptr); + } OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl) - : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) {} + : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) { + assert(FunctionTemplateDecl != nullptr); + } OverloadCandidate(const FunctionType *Type) - : Kind(CK_FunctionType), Type(Type) {} + : Kind(CK_FunctionType), Type(Type) { + assert(Type != nullptr); + } + + OverloadCandidate(const RecordDecl *Aggregate) + : Kind(CK_Aggregate), AggregateType(Aggregate) { + assert(Aggregate != nullptr); + } + + OverloadCandidate(const TemplateDecl *Template) + : Kind(CK_Template), Template(Template) {} /// Determine the kind of overload candidate. CandidateKind getKind() const { return Kind; } @@ -1062,13 +1090,35 @@ public: /// function is stored. const FunctionType *getFunctionType() const; + const TemplateDecl *getTemplate() const { + assert(getKind() == CK_Template && "Not a template"); + return Template; + } + + /// Retrieve the aggregate type being initialized. + const RecordDecl *getAggregate() const { + assert(getKind() == CK_Aggregate); + return AggregateType; + } + + /// Get the number of parameters in this signature. + unsigned getNumParams() const; + + /// Get the type of the Nth parameter. + /// Returns null if the type is unknown or N is out of range. + QualType getParamType(unsigned N) const; + + /// Get the declaration of the Nth parameter. + /// Returns null if the decl is unknown or N is out of range. + const NamedDecl *getParamDecl(unsigned N) const; + /// Create a new code-completion string that describes the function /// signature of this overload candidate. - CodeCompletionString *CreateSignatureString(unsigned CurrentArg, - Sema &S, - CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - bool IncludeBriefComments) const; + CodeCompletionString * + CreateSignatureString(unsigned CurrentArg, Sema &S, + CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo, + bool IncludeBriefComments, bool Braced) const; }; CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts) @@ -1142,7 +1192,8 @@ public: virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, OverloadCandidate *Candidates, unsigned NumCandidates, - SourceLocation OpenParLoc) {} + SourceLocation OpenParLoc, + bool Braced) {} //@} /// Retrieve the allocator that will be used to allocate @@ -1193,7 +1244,8 @@ public: void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, OverloadCandidate *Candidates, unsigned NumCandidates, - SourceLocation OpenParLoc) override; + SourceLocation OpenParLoc, + bool Braced) override; bool isResultFilteredOut(StringRef Filter, CodeCompletionResult Results) override; diff --git contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h index 2704a9c1fc78..2437be497de4 100644 --- contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h +++ contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h @@ -434,8 +434,7 @@ public: FS_noreturn_specified(false), Friend_specified(false), ConstexprSpecifier( static_cast<unsigned>(ConstexprSpecKind::Unspecified)), - FS_explicit_specifier(), Attrs(attrFactory), writtenBS(), - ObjCQualifiers(nullptr) {} + Attrs(attrFactory), writtenBS(), ObjCQualifiers(nullptr) {} // storage-class-specifier SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; } diff --git contrib/llvm-project/clang/include/clang/Sema/ExternalSemaSource.h contrib/llvm-project/clang/include/clang/Sema/ExternalSemaSource.h index 9c18aa1398d3..17a7ffd3bb68 100644 --- contrib/llvm-project/clang/include/clang/Sema/ExternalSemaSource.h +++ contrib/llvm-project/clang/include/clang/Sema/ExternalSemaSource.h @@ -26,11 +26,9 @@ template <class T, unsigned n> class SmallSetVector; namespace clang { class CXXConstructorDecl; -class CXXDeleteExpr; class CXXRecordDecl; class DeclaratorDecl; class LookupResult; -struct ObjCMethodList; class Scope; class Sema; class TypedefNameDecl; diff --git contrib/llvm-project/clang/include/clang/Sema/Initialization.h contrib/llvm-project/clang/include/clang/Sema/Initialization.h index 679e12ee22d4..21adc9fa2ac0 100644 --- contrib/llvm-project/clang/include/clang/Sema/Initialization.h +++ contrib/llvm-project/clang/include/clang/Sema/Initialization.h @@ -38,7 +38,6 @@ namespace clang { -class APValue; class CXXBaseSpecifier; class CXXConstructorDecl; class ObjCMethodDecl; diff --git contrib/llvm-project/clang/include/clang/Sema/Overload.h contrib/llvm-project/clang/include/clang/Sema/Overload.h index 88405a63b735..48997e186ef6 100644 --- contrib/llvm-project/clang/include/clang/Sema/Overload.h +++ contrib/llvm-project/clang/include/clang/Sema/Overload.h @@ -577,8 +577,7 @@ class Sema; ImplicitConversionSequence() : ConversionKind(Uninitialized), - InitializerListOfIncompleteArray(false), - InitializerListContainerType() { + InitializerListOfIncompleteArray(false) { Standard.setAsIdentityConversion(); } diff --git contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h index 6403179cb327..4fa6f09d3321 100644 --- contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h +++ contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H -#define LLVM_CLANG_SEMA_ATTRIBUTELIST_H +#ifndef LLVM_CLANG_SEMA_PARSEDATTR_H +#define LLVM_CLANG_SEMA_PARSEDATTR_H #include "clang/Basic/AttrSubjectMatchRules.h" #include "clang/Basic/AttributeCommonInfo.h" @@ -1080,7 +1080,7 @@ struct ParsedAttributesWithRange : ParsedAttributes { SourceRange Range; }; struct ParsedAttributesViewWithRange : ParsedAttributesView { - ParsedAttributesViewWithRange() : ParsedAttributesView() {} + ParsedAttributesViewWithRange() {} void clearListOnly() { ParsedAttributesView::clearListOnly(); Range = SourceRange(); @@ -1159,4 +1159,4 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, } // namespace clang -#endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H +#endif // LLVM_CLANG_SEMA_PARSEDATTR_H diff --git contrib/llvm-project/clang/include/clang/Sema/ParsedTemplate.h contrib/llvm-project/clang/include/clang/Sema/ParsedTemplate.h index f0245b93c7eb..926cec2c547c 100644 --- contrib/llvm-project/clang/include/clang/Sema/ParsedTemplate.h +++ contrib/llvm-project/clang/include/clang/Sema/ParsedTemplate.h @@ -63,8 +63,7 @@ namespace clang { ParsedTemplateTy Template, SourceLocation TemplateLoc) : Kind(ParsedTemplateArgument::Template), - Arg(Template.getAsOpaquePtr()), - SS(SS), Loc(TemplateLoc), EllipsisLoc() { } + Arg(Template.getAsOpaquePtr()), SS(SS), Loc(TemplateLoc) {} /// Determine whether the given template argument is invalid. bool isInvalid() const { return Arg == nullptr; } diff --git contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h index ccd15ea6a818..08bf53d22f8a 100644 --- contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h +++ contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h @@ -58,7 +58,6 @@ class Scope; class Stmt; class SwitchStmt; class TemplateParameterList; -class TemplateTypeParmDecl; class VarDecl; namespace sema { diff --git contrib/llvm-project/clang/include/clang/Sema/Sema.h contrib/llvm-project/clang/include/clang/Sema/Sema.h index 79834554a50d..4b609f4b1477 100644 --- contrib/llvm-project/clang/include/clang/Sema/Sema.h +++ contrib/llvm-project/clang/include/clang/Sema/Sema.h @@ -1365,10 +1365,10 @@ public: }; private: - llvm::PointerIntPair<CXXMethodDecl*, 2> Pair; + llvm::PointerIntPair<CXXMethodDecl *, 2> Pair; public: - SpecialMemberOverloadResult() : Pair() {} + SpecialMemberOverloadResult() {} SpecialMemberOverloadResult(CXXMethodDecl *MD) : Pair(MD, MD->isDeleted() ? NoMemberOrDeleted : Success) {} @@ -1565,8 +1565,11 @@ public: /// assignment. llvm::DenseMap<const VarDecl *, int> RefsMinusAssignments; +private: Optional<std::unique_ptr<DarwinSDKInfo>> CachedDarwinSDKInfo; + bool WarnedDarwinSDKInfoMissing = false; + public: Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind = TU_Complete, @@ -1595,8 +1598,10 @@ public: ASTConsumer &getASTConsumer() const { return Consumer; } ASTMutationListener *getASTMutationListener() const; ExternalSemaSource* getExternalSource() const { return ExternalSource; } + DarwinSDKInfo *getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc, StringRef Platform); + DarwinSDKInfo *getDarwinSDKInfoForAvailabilityChecking(); ///Registers an external source. If an external source already exists, /// creates a multiplex external source and appends to it. @@ -4315,6 +4320,8 @@ public: bool ConsiderLinkage, bool AllowInlineNamespace); bool CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old); + bool CheckRedeclarationExported(NamedDecl *New, NamedDecl *Old); + bool CheckRedeclarationInModule(NamedDecl *New, NamedDecl *Old); void DiagnoseAmbiguousLookup(LookupResult &Result); //@} @@ -4861,7 +4868,8 @@ public: StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope); - StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); + StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, + bool AllowRecovery = false); StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, NamedReturnInfo &NRInfo, bool SupressSimplerImplicitMoves); @@ -5052,6 +5060,7 @@ public: void DiscardCleanupsInEvaluationContext(); ExprResult TransformToPotentiallyEvaluated(Expr *E); + TypeSourceInfo *TransformToPotentiallyEvaluated(TypeSourceInfo *TInfo); ExprResult HandleExprEvaluationContextForTypeof(Expr *E); ExprResult CheckUnevaluatedOperand(Expr *E); @@ -7520,7 +7529,7 @@ public: RequiredTemplateKind(SourceLocation TemplateKWLoc = SourceLocation()) : TemplateKW(TemplateKWLoc) {} /// Template name is unconditionally required. - RequiredTemplateKind(TemplateNameIsRequiredTag) : TemplateKW() {} + RequiredTemplateKind(TemplateNameIsRequiredTag) {} SourceLocation getTemplateKeywordLoc() const { return TemplateKW.getValueOr(SourceLocation()); @@ -10332,6 +10341,9 @@ private: /// The directive kind, `begin declare target` or `declare target`. OpenMPDirectiveKind Kind; + /// The directive with indirect clause. + Optional<Expr *> Indirect; + /// The directive location. SourceLocation Loc; @@ -10638,7 +10650,7 @@ public: /// Called on correct id-expression from the '#pragma omp declare target'. void ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, - OMPDeclareTargetDeclAttr::DevTypeTy DT); + DeclareTargetContextInfo &DTCI); /// Check declaration inside target region. void @@ -12079,9 +12091,12 @@ public: ConstexprIf, ///< A constant boolean condition from 'if constexpr'. Switch ///< An integral condition for a 'switch' statement. }; + QualType PreferredConditionType(ConditionKind K) const { + return K == ConditionKind::Switch ? Context.IntTy : Context.BoolTy; + } - ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, - Expr *SubExpr, ConditionKind CK); + ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, Expr *SubExpr, + ConditionKind CK, bool MissingOK = false); ConditionResult ActOnConditionVariable(Decl *ConditionVar, SourceLocation StmtLoc, @@ -12537,18 +12552,18 @@ public: /// signatures that were considered. /// /// FIXME: rename to GuessCallArgumentType to reduce confusion. - QualType ProduceCallSignatureHelp(Scope *S, Expr *Fn, ArrayRef<Expr *> Args, + QualType ProduceCallSignatureHelp(Expr *Fn, ArrayRef<Expr *> Args, SourceLocation OpenParLoc); - QualType ProduceConstructorSignatureHelp(Scope *S, QualType Type, - SourceLocation Loc, + QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef<Expr *> Args, - SourceLocation OpenParLoc); - QualType ProduceCtorInitMemberSignatureHelp(Scope *S, Decl *ConstructorDecl, - CXXScopeSpec SS, - ParsedType TemplateTypeTy, - ArrayRef<Expr *> ArgExprs, - IdentifierInfo *II, - SourceLocation OpenParLoc); + SourceLocation OpenParLoc, + bool Braced); + QualType ProduceCtorInitMemberSignatureHelp( + Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy, + ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc, + bool Braced); + QualType ProduceTemplateArgumentSignatureHelp( + TemplateTy, ArrayRef<ParsedTemplateArgument>, SourceLocation LAngleLoc); void CodeCompleteInitializer(Scope *S, Decl *D); /// Trigger code completion for a record of \p BaseType. \p InitExprs are /// expressions in the initializer list seen so far and \p D is the current @@ -13061,7 +13076,7 @@ private: ValueDecl *MD; CharUnits Alignment; - MisalignedMember() : E(), RD(), MD(), Alignment() {} + MisalignedMember() : E(), RD(), MD() {} MisalignedMember(Expr *E, RecordDecl *RD, ValueDecl *MD, CharUnits Alignment) : E(E), RD(RD), MD(MD), Alignment(Alignment) {} @@ -13142,6 +13157,9 @@ public: /// Adds Callee to DeviceCallGraph if we don't know if its caller will be /// codegen'ed yet. bool checkSYCLDeviceFunction(SourceLocation Loc, FunctionDecl *Callee); + void deepTypeCheckForSYCLDevice(SourceLocation UsedAt, + llvm::DenseSet<QualType> Visited, + ValueDecl *DeclToCheck); }; /// RAII object that enters a new expression evaluation context. diff --git contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h index dc5f0ec97e85..b73a152533d1 100644 --- contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h +++ contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h @@ -152,4 +152,4 @@ private: } // clang -#endif //LLVM_CLANG_SEMA_SEMACONCEPT_H +#endif // LLVM_CLANG_SEMA_SEMACONCEPT_H diff --git contrib/llvm-project/clang/include/clang/Sema/TemplateInstCallback.h contrib/llvm-project/clang/include/clang/Sema/TemplateInstCallback.h index 3ab0e8c6be9f..9258a7f41ac1 100644 --- contrib/llvm-project/clang/include/clang/Sema/TemplateInstCallback.h +++ contrib/llvm-project/clang/include/clang/Sema/TemplateInstCallback.h @@ -11,8 +11,8 @@ // //===---------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TEMPLATE_INST_CALLBACK_H -#define LLVM_CLANG_TEMPLATE_INST_CALLBACK_H +#ifndef LLVM_CLANG_SEMA_TEMPLATEINSTCALLBACK_H +#define LLVM_CLANG_SEMA_TEMPLATEINSTCALLBACK_H #include "clang/Sema/Sema.h" diff --git contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h index 341da5bd1d62..f98e173b158c 100644 --- contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h +++ contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h @@ -695,6 +695,9 @@ enum ASTRecordTypes { /// Record code for \#pragma float_control options. FLOAT_CONTROL_PRAGMA_OPTIONS = 65, + + /// Record code for included files. + PP_INCLUDED_FILES = 66, }; /// Record types used within a source manager block. diff --git contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h index f24ccf579aa8..d46a6c4500f4 100644 --- contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h +++ contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h @@ -84,7 +84,6 @@ class GlobalModuleIndex; struct HeaderFileInfo; class HeaderSearchOptions; class LangOptions; -class LazyASTUnresolvedSet; class MacroInfo; class InMemoryModuleCache; class NamedDecl; @@ -94,7 +93,6 @@ class ObjCInterfaceDecl; class PCHContainerReader; class Preprocessor; class PreprocessorOptions; -struct QualifierInfo; class Sema; class SourceManager; class Stmt; @@ -1331,6 +1329,7 @@ private: llvm::Error ReadSourceManagerBlock(ModuleFile &F); llvm::BitstreamCursor &SLocCursorForID(int ID); SourceLocation getImportLocation(ModuleFile *F); + void readIncludedFiles(ModuleFile &F, StringRef Blob, Preprocessor &PP); ASTReadResult ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, const ModuleFile *ImportedBy, unsigned ClientLoadCapabilities); diff --git contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h index 978f6d86ea5c..e455e4d4d96a 100644 --- contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h +++ contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h @@ -43,26 +43,13 @@ #include <utility> #include <vector> -namespace llvm { - -class APFloat; -class APInt; -class APSInt; - -} // namespace llvm - namespace clang { class ASTContext; class ASTReader; -class ASTUnresolvedSet; class Attr; -class CXXBaseSpecifier; -class CXXCtorInitializer; class CXXRecordDecl; -class CXXTemporary; class FileEntry; -class FPOptions; class FPOptionsOverride; class FunctionDecl; class HeaderSearch; @@ -79,16 +66,13 @@ class NamedDecl; class ObjCInterfaceDecl; class PreprocessingRecord; class Preprocessor; -struct QualifierInfo; class RecordDecl; class Sema; class SourceManager; class Stmt; class StoredDeclsList; class SwitchCase; -class TemplateParameterList; class Token; -class TypeSourceInfo; /// Writes an AST file containing the contents of a translation unit. /// @@ -481,6 +465,7 @@ private: std::set<const FileEntry *> &AffectingModuleMaps); void WriteSourceManagerBlock(SourceManager &SourceMgr, const Preprocessor &PP); + void writeIncludedFiles(raw_ostream &Out, const Preprocessor &PP); void WritePreprocessor(const Preprocessor &PP, bool IsModule); void WriteHeaderSearch(const HeaderSearch &HS); void WritePreprocessorDetail(PreprocessingRecord &PPRec, diff --git contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h index 5f4812626224..9d6b52a97f52 100644 --- contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h +++ contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h @@ -31,8 +31,6 @@ class MemoryBuffer; namespace clang { -class DirectoryEntry; -class FileEntry; class FileManager; class IdentifierIterator; class PCHContainerOperations; diff --git contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h index 3e84a65c4b80..2168ce2ce607 100644 --- contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h +++ contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h @@ -154,4 +154,4 @@ public: } // end namespace clang -#endif // LLVM_CLANG_FRONTEND_MODULEFILEEXTENSION_H +#endif // LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H diff --git contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h index 7081eedad4b4..4305bae5ee95 100644 --- contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h +++ contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h @@ -105,10 +105,6 @@ class ModuleManager { Stack.reserve(N); } - ~VisitState() { - delete NextState; - } - /// The stack used when marking the imports of a particular module /// as not-to-be-visited. SmallVector<ModuleFile *, 4> Stack; @@ -121,14 +117,14 @@ class ModuleManager { unsigned NextVisitNumber = 1; /// The next visit state. - VisitState *NextState = nullptr; + std::unique_ptr<VisitState> NextState; }; /// The first visit() state in the chain. - VisitState *FirstVisitState = nullptr; + std::unique_ptr<VisitState> FirstVisitState; - VisitState *allocateVisitState(); - void returnVisitState(VisitState *State); + std::unique_ptr<VisitState> allocateVisitState(); + void returnVisitState(std::unique_ptr<VisitState> State); public: using ModuleIterator = llvm::pointee_iterator< @@ -142,7 +138,6 @@ public: explicit ModuleManager(FileManager &FileMgr, InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, const HeaderSearch &HeaderSearchInfo); - ~ModuleManager(); /// Forward iterator to traverse all loaded modules. ModuleIterator begin() { return Chain.begin(); } diff --git contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h index 33fc4a0a24e0..9f9700a418a9 100644 --- contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h +++ contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h @@ -22,8 +22,6 @@ class raw_pwrite_stream; namespace clang { class ASTConsumer; -class CodeGenOptions; -class DiagnosticsEngine; class CompilerInstance; struct PCHBuffer { diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h index e2be957821b9..bdfe3901c5b8 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h @@ -11,19 +11,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_CLANGSACHECKERS_H -#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_CLANGSACHECKERS_H +#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_BUILTINCHECKERREGISTRATION_H +#define LLVM_CLANG_STATICANALYZER_CHECKERS_BUILTINCHECKERREGISTRATION_H #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" namespace clang { - -class LangOptions; - namespace ento { class CheckerManager; -class CheckerRegistry; #define GET_CHECKERS #define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \ diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h index bbc5111ccacc..6243bbd5d53b 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h @@ -11,8 +11,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIFUNCTIONCLASSIFIER_H -#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIFUNCTIONCLASSIFIER_H +#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_MPIFUNCTIONCLASSIFIER_H +#define LLVM_CLANG_STATICANALYZER_CHECKERS_MPIFUNCTIONCLASSIFIER_H #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def index c0cade46d614..7b976ddeaba2 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def @@ -320,6 +320,11 @@ ANALYZER_OPTION(bool, ShouldDisplayCheckerNameForText, "display-checker-name", "Display the checker name for textual outputs", true) +ANALYZER_OPTION(bool, ShouldSupportSymbolicIntegerCasts, + "support-symbolic-integer-casts", + "Produce cast symbols for integral types.", + false) + ANALYZER_OPTION( bool, ShouldConsiderSingleElementArraysAsFlexibleArrayMembers, "consider-single-element-arrays-as-flexible-array-members", diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 3c93ebeccde8..9ec5bcc87554 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -48,7 +48,6 @@ namespace clang { class AnalyzerOptions; class ASTContext; class Decl; -class DiagnosticsEngine; class LocationContext; class SourceManager; class Stmt; @@ -61,7 +60,6 @@ class ExplodedGraph; class ExplodedNode; class ExprEngine; class MemRegion; -class SValBuilder; //===----------------------------------------------------------------------===// // Interface for individual bug reports. diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h index 49ab25eca2dd..558881176327 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h @@ -23,8 +23,6 @@ namespace clang { namespace ento { class BugReporter; -class ExplodedNode; -class ExprEngine; class BugType { private: diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index d2f71baa56a4..7e45d24e5695 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -28,7 +28,6 @@ namespace clang { class AnalyzerOptions; class CallExpr; -class CXXNewExpr; class Decl; class LocationContext; class Stmt; diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h index 71a590d9e9a2..2694aac478cd 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h @@ -20,7 +20,6 @@ namespace clang { -class AnalyzerOptions; class MacroExpansionContext; class Preprocessor; diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index bb598af68166..8a778389bcbe 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -34,7 +34,6 @@ namespace clang { class CXXBaseSpecifier; -class DeclaratorDecl; namespace ento { diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index d135e70dd75d..bfaeb06951d7 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -76,7 +76,6 @@ enum CallEventKind { }; class CallEvent; -class CallDescription; template<typename T = CallEvent> class CallEventRef : public IntrusiveRefCntPtr<const T> { diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index a383012dc351..94fa0d9ecdc3 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -84,6 +84,8 @@ public: return Eng.getContext(); } + const ASTContext &getASTContext() const { return Eng.getContext(); } + const LangOptions &getLangOpts() const { return Eng.getContext().getLangOpts(); } diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h index a81d67ab3063..e89a993ca8d2 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h @@ -24,7 +24,6 @@ namespace clang { class Expr; class VarDecl; class QualType; -class AttributedType; class Preprocessor; namespace ento { diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h index 6d2b495dc0f5..3ff453a8de4f 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h @@ -18,7 +18,7 @@ namespace ento { /// of a region in a given state along the analysis path. class DynamicTypeInfo { public: - DynamicTypeInfo() : DynTy(QualType()) {} + DynamicTypeInfo() {} DynamicTypeInfo(QualType Ty, bool CanBeSub = true) : DynTy(Ty), CanBeASubClass(CanBeSub) {} diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index cef7dda172f3..feb4a72fe8d0 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -77,13 +77,9 @@ namespace ento { class AnalysisManager; class BasicValueFactory; -class BlockCounter; -class BranchNodeBuilder; class CallEvent; class CheckerManager; class ConstraintManager; -class CXXTempObjectRegion; -class EndOfFunctionNodeBuilder; class ExplodedNodeSet; class ExplodedNode; class IndirectGotoNodeBuilder; diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h index 53b221cb53c9..eb2b0b343428 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h @@ -28,7 +28,6 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" namespace clang { namespace ento { -class AnalysisManager; /// Returns if the given State indicates that is inside a completely unrolled /// loop. diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index 9a34639e2707..3204ac460ed0 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -47,8 +47,6 @@ typedef std::unique_ptr<StoreManager>(*StoreManagerCreator)( // ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState. //===----------------------------------------------------------------------===// -template <typename T> struct ProgramStatePartialTrait; - template <typename T> struct ProgramStateTrait { typedef typename T::data_type data_type; static inline void *MakeVoidPtr(data_type D) { return (void*) D; } diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h index 3a0bec9d04e5..6c487697bc55 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LIB_STATICANALYZER_CORE_RANGEDCONSTRAINTMANAGER_H -#define LLVM_CLANG_LIB_STATICANALYZER_CORE_RANGEDCONSTRAINTMANAGER_H +#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_RANGEDCONSTRAINTMANAGER_H +#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_RANGEDCONSTRAINTMANAGER_H #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index 61dfdbb0688b..1df47dae25bf 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -96,6 +96,17 @@ protected: QualType OriginalTy); SVal evalCastSubKind(nonloc::PointerToMember V, QualType CastTy, QualType OriginalTy); + /// Reduce cast expression by removing redundant intermediate casts. + /// E.g. + /// - (char)(short)(int x) -> (char)(int x) + /// - (int)(int x) -> int x + /// + /// \param V -- SymbolVal, which pressumably contains SymbolCast or any symbol + /// that is applicable for cast operation. + /// \param CastTy -- QualType, which `V` shall be cast to. + /// \return SVal with simplified cast expression. + /// \note: Currently only support integral casts. + SVal simplifySymbolCast(nonloc::SymbolVal V, QualType CastTy); public: SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, @@ -103,18 +114,6 @@ public: virtual ~SValBuilder() = default; - bool haveSameType(const SymExpr *Sym1, const SymExpr *Sym2) { - return haveSameType(Sym1->getType(), Sym2->getType()); - } - - bool haveSameType(QualType Ty1, QualType Ty2) { - // FIXME: Remove the second disjunct when we support symbolic - // truncation/extension. - return (Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2) || - (Ty1->isIntegralOrEnumerationType() && - Ty2->isIntegralOrEnumerationType())); - } - SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy); // Handles casts of type CK_IntegralCast. diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index 6199c8d8d179..f4b229070d67 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -35,7 +35,6 @@ namespace clang { class CXXBaseSpecifier; -class DeclaratorDecl; class FunctionDecl; class LabelDecl; diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h index bcc29a60ad70..f3b1c1f20645 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h @@ -21,14 +21,10 @@ namespace clang { -class Preprocessor; -class DiagnosticsEngine; -class CodeInjector; class CompilerInstance; namespace ento { class PathDiagnosticConsumer; -class CheckerManager; class CheckerRegistry; class AnalysisASTConsumer : public ASTConsumer { diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h index 2b12330e4f2d..31b1c245200e 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h @@ -16,12 +16,9 @@ namespace clang { class Stmt; -class AnalyzerOptions; namespace ento { -class CheckerManager; - //===----------------------------------------------------------------------===// // AST Consumer Actions //===----------------------------------------------------------------------===// diff --git contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h index 5f9ae78dac63..7b7087622bc2 100644 --- contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h +++ contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h @@ -12,8 +12,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_GR_MODELCONSUMER_H -#define LLVM_CLANG_GR_MODELCONSUMER_H +#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_MODELCONSUMER_H +#define LLVM_CLANG_STATICANALYZER_FRONTEND_MODELCONSUMER_H #include "clang/AST/ASTConsumer.h" #include "llvm/ADT/StringMap.h" diff --git contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiff.h contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiff.h index c772ad84c139..5fe6db6cb133 100644 --- contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiff.h +++ contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiff.h @@ -48,20 +48,6 @@ struct Node { llvm::Optional<std::string> getQualifiedIdentifier() const; }; -class ASTDiff { -public: - ASTDiff(SyntaxTree &Src, SyntaxTree &Dst, const ComparisonOptions &Options); - ~ASTDiff(); - - // Returns the ID of the node that is mapped to the given node in SourceTree. - NodeId getMapped(const SyntaxTree &SourceTree, NodeId Id) const; - - class Impl; - -private: - std::unique_ptr<Impl> DiffImpl; -}; - /// SyntaxTree objects represent subtrees of the AST. /// They can be constructed from any Decl or Stmt. class SyntaxTree { @@ -120,6 +106,20 @@ struct ComparisonOptions { } }; +class ASTDiff { +public: + ASTDiff(SyntaxTree &Src, SyntaxTree &Dst, const ComparisonOptions &Options); + ~ASTDiff(); + + // Returns the ID of the node that is mapped to the given node in SourceTree. + NodeId getMapped(const SyntaxTree &SourceTree, NodeId Id) const; + + class Impl; + +private: + std::unique_ptr<Impl> DiffImpl; +}; + } // end namespace diff } // end namespace clang diff --git contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h index 1e784ef43ac1..b74af5e8f24f 100644 --- contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h +++ contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h @@ -17,10 +17,6 @@ namespace diff { using DynTypedNode = DynTypedNode; -class SyntaxTree; -class SyntaxTreeImpl; -struct ComparisonOptions; - /// Within a tree, this identifies a node by its preorder offset. struct NodeId { private: diff --git contrib/llvm-project/clang/include/clang/Tooling/CommonOptionsParser.h contrib/llvm-project/clang/include/clang/Tooling/CommonOptionsParser.h index 0f072c2886ab..3c0480af3779 100644 --- contrib/llvm-project/clang/include/clang/Tooling/CommonOptionsParser.h +++ contrib/llvm-project/clang/include/clang/Tooling/CommonOptionsParser.h @@ -141,4 +141,4 @@ private: } // namespace tooling } // namespace clang -#endif // LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H +#endif // LLVM_CLANG_TOOLING_COMMONOPTIONSPARSER_H diff --git contrib/llvm-project/clang/include/clang/Tooling/CompilationDatabase.h contrib/llvm-project/clang/include/clang/Tooling/CompilationDatabase.h index 90af15536961..fee584acb486 100644 --- contrib/llvm-project/clang/include/clang/Tooling/CompilationDatabase.h +++ contrib/llvm-project/clang/include/clang/Tooling/CompilationDatabase.h @@ -216,6 +216,8 @@ private: /// Transforms a compile command so that it applies the same configuration to /// a different file. Most args are left intact, but tweaks may be needed /// to certain flags (-x, -std etc). +/// +/// The output command will always end in {"--", Filename}. tooling::CompileCommand transferCompileCommand(tooling::CompileCommand, StringRef Filename); diff --git contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h index 7d0b8f2138f9..7c830d3f2733 100644 --- contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h +++ contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_FILESYSTEM_H -#define LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_FILESYSTEM_H +#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H +#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H #include "clang/Basic/LLVM.h" #include "clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSet.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/VirtualFileSystem.h" @@ -22,6 +22,26 @@ namespace clang { namespace tooling { namespace dependencies { +/// Original and minimized contents of a cached file entry. Single instance can +/// be shared between multiple entries. +struct CachedFileContents { + CachedFileContents(std::unique_ptr<llvm::MemoryBuffer> Original) + : Original(std::move(Original)), MinimizedAccess(nullptr) {} + + /// Owning storage for the minimized contents. + std::unique_ptr<llvm::MemoryBuffer> Original; + + /// The mutex that must be locked before mutating minimized contents. + std::mutex ValueLock; + /// Owning storage for the minimized contents. + std::unique_ptr<llvm::MemoryBuffer> MinimizedStorage; + /// Accessor to the minimized contents that's atomic to avoid data races. + std::atomic<llvm::MemoryBuffer *> MinimizedAccess; + /// Skipped range mapping of the minimized contents. + /// This is initialized iff `MinimizedAccess != nullptr`. + PreprocessorSkippedRangeMapping PPSkippedRangeMapping; +}; + /// An in-memory representation of a file system entity that is of interest to /// the dependency scanning filesystem. /// @@ -29,100 +49,99 @@ namespace dependencies { /// - opened file with original contents and a stat value, /// - opened file with original contents, minimized contents and a stat value, /// - directory entry with its stat value, -/// - filesystem error, -/// - uninitialized entry with unknown status. +/// - filesystem error. +/// +/// Single instance of this class can be shared across different filenames (e.g. +/// a regular file and a symlink). For this reason the status filename is empty +/// and is only materialized by \c EntryRef that knows the requested filename. class CachedFileSystemEntry { public: - /// Creates an uninitialized entry. - CachedFileSystemEntry() - : MaybeStat(llvm::vfs::Status()), MinimizedContentsAccess(nullptr) {} - - /// Initialize the cached file system entry. - void init(llvm::ErrorOr<llvm::vfs::Status> &&MaybeStatus, StringRef Filename, - llvm::vfs::FileSystem &FS); + /// Creates an entry without contents: either a filesystem error or + /// a directory with stat value. + CachedFileSystemEntry(llvm::ErrorOr<llvm::vfs::Status> Stat) + : MaybeStat(std::move(Stat)), Contents(nullptr) { + clearStatName(); + } - /// Initialize the entry as file with minimized or original contents. - /// - /// The filesystem opens the file even for `stat` calls open to avoid the - /// issues with stat + open of minimized files that might lead to a - /// mismatching size of the file. - llvm::ErrorOr<llvm::vfs::Status> initFile(StringRef Filename, - llvm::vfs::FileSystem &FS); - - /// Minimize contents of the file. - void minimizeFile(); - - /// \returns True if the entry is initialized. - bool isInitialized() const { - return !MaybeStat || MaybeStat->isStatusKnown(); + /// Creates an entry representing a file with contents. + CachedFileSystemEntry(llvm::ErrorOr<llvm::vfs::Status> Stat, + CachedFileContents *Contents) + : MaybeStat(std::move(Stat)), Contents(std::move(Contents)) { + clearStatName(); } - /// \returns True if the current entry points to a directory. - bool isDirectory() const { return MaybeStat && MaybeStat->isDirectory(); } + /// \returns True if the entry is a filesystem error. + bool isError() const { return !MaybeStat; } + + /// \returns True if the current entry represents a directory. + bool isDirectory() const { return !isError() && MaybeStat->isDirectory(); } - /// \returns The error or the file's original contents. - llvm::ErrorOr<StringRef> getOriginalContents() const { - if (!MaybeStat) - return MaybeStat.getError(); + /// \returns Original contents of the file. + StringRef getOriginalContents() const { + assert(!isError() && "error"); assert(!MaybeStat->isDirectory() && "not a file"); - assert(isInitialized() && "not initialized"); - assert(OriginalContents && "not read"); - return OriginalContents->getBuffer(); + assert(Contents && "contents not initialized"); + return Contents->Original->getBuffer(); } - /// \returns The error or the file's minimized contents. - llvm::ErrorOr<StringRef> getMinimizedContents() const { - if (!MaybeStat) - return MaybeStat.getError(); + /// \returns Minimized contents of the file. + StringRef getMinimizedContents() const { + assert(!isError() && "error"); assert(!MaybeStat->isDirectory() && "not a file"); - assert(isInitialized() && "not initialized"); - llvm::MemoryBuffer *Buffer = MinimizedContentsAccess.load(); + assert(Contents && "contents not initialized"); + llvm::MemoryBuffer *Buffer = Contents->MinimizedAccess.load(); assert(Buffer && "not minimized"); return Buffer->getBuffer(); } - /// \returns True if this entry represents a file that can be read. - bool isReadable() const { return MaybeStat && !MaybeStat->isDirectory(); } + /// \returns The error. + std::error_code getError() const { return MaybeStat.getError(); } - /// \returns True if this cached entry needs to be updated. - bool needsUpdate(bool ShouldBeMinimized) const { - return isReadable() && needsMinimization(ShouldBeMinimized); + /// \returns The entry status with empty filename. + llvm::vfs::Status getStatus() const { + assert(!isError() && "error"); + assert(MaybeStat->getName().empty() && "stat name must be empty"); + return *MaybeStat; } - /// \returns True if the contents of this entry need to be minimized. - bool needsMinimization(bool ShouldBeMinimized) const { - return ShouldBeMinimized && !MinimizedContentsAccess.load(); + /// \returns The unique ID of the entry. + llvm::sys::fs::UniqueID getUniqueID() const { + assert(!isError() && "error"); + return MaybeStat->getUniqueID(); } - /// \returns The error or the status of the entry. - llvm::ErrorOr<llvm::vfs::Status> getStatus() const { - assert(isInitialized() && "not initialized"); - return MaybeStat; + /// \returns The mapping between location -> distance that is used to speed up + /// the block skipping in the preprocessor. + const PreprocessorSkippedRangeMapping &getPPSkippedRangeMapping() const { + assert(!isError() && "error"); + assert(!isDirectory() && "not a file"); + assert(Contents && "contents not initialized"); + return Contents->PPSkippedRangeMapping; } - /// \returns the name of the file. - StringRef getName() const { - assert(isInitialized() && "not initialized"); - return MaybeStat->getName(); + /// \returns The data structure holding both original and minimized contents. + CachedFileContents *getContents() const { + assert(!isError() && "error"); + assert(!isDirectory() && "not a file"); + return Contents; } - /// Return the mapping between location -> distance that is used to speed up - /// the block skipping in the preprocessor. - const PreprocessorSkippedRangeMapping &getPPSkippedRangeMapping() const { - return PPSkippedRangeMapping; +private: + void clearStatName() { + if (MaybeStat) + MaybeStat = llvm::vfs::Status::copyWithNewName(*MaybeStat, ""); } -private: + /// Either the filesystem error or status of the entry. + /// The filename is empty and only materialized by \c EntryRef. llvm::ErrorOr<llvm::vfs::Status> MaybeStat; - std::unique_ptr<llvm::MemoryBuffer> OriginalContents; - - /// Owning storage for the minimized file contents. - std::unique_ptr<llvm::MemoryBuffer> MinimizedContentsStorage; - /// Atomic view of the minimized file contents. - /// This prevents data races when multiple threads call `needsMinimization`. - std::atomic<llvm::MemoryBuffer *> MinimizedContentsAccess; - PreprocessorSkippedRangeMapping PPSkippedRangeMapping; + /// Non-owning pointer to the file contents. + /// + /// We're using pointer here to keep the size of this class small. Instances + /// representing directories and filesystem errors don't hold any contents + /// anyway. + CachedFileContents *Contents; }; /// This class is a shared cache, that caches the 'stat' and 'open' calls to the @@ -133,24 +152,59 @@ private: /// the worker threads. class DependencyScanningFilesystemSharedCache { public: - struct SharedFileSystemEntry { - std::mutex ValueLock; - CachedFileSystemEntry Value; + struct CacheShard { + /// The mutex that needs to be locked before mutation of any member. + mutable std::mutex CacheLock; + + /// Map from filenames to cached entries. + llvm::StringMap<const CachedFileSystemEntry *, llvm::BumpPtrAllocator> + EntriesByFilename; + + /// Map from unique IDs to cached entries. + llvm::DenseMap<llvm::sys::fs::UniqueID, const CachedFileSystemEntry *> + EntriesByUID; + + /// The backing storage for cached entries. + llvm::SpecificBumpPtrAllocator<CachedFileSystemEntry> EntryStorage; + + /// The backing storage for cached contents. + llvm::SpecificBumpPtrAllocator<CachedFileContents> ContentsStorage; + + /// Returns entry associated with the filename or nullptr if none is found. + const CachedFileSystemEntry *findEntryByFilename(StringRef Filename) const; + + /// Returns entry associated with the unique ID or nullptr if none is found. + const CachedFileSystemEntry * + findEntryByUID(llvm::sys::fs::UniqueID UID) const; + + /// Returns entry associated with the filename if there is some. Otherwise, + /// constructs new one with the given status, associates it with the + /// filename and returns the result. + const CachedFileSystemEntry & + getOrEmplaceEntryForFilename(StringRef Filename, + llvm::ErrorOr<llvm::vfs::Status> Stat); + + /// Returns entry associated with the unique ID if there is some. Otherwise, + /// constructs new one with the given status and contents, associates it + /// with the unique ID and returns the result. + const CachedFileSystemEntry & + getOrEmplaceEntryForUID(llvm::sys::fs::UniqueID UID, llvm::vfs::Status Stat, + std::unique_ptr<llvm::MemoryBuffer> Contents); + + /// Returns entry associated with the filename if there is some. Otherwise, + /// associates the given entry with the filename and returns it. + const CachedFileSystemEntry & + getOrInsertEntryForFilename(StringRef Filename, + const CachedFileSystemEntry &Entry); }; DependencyScanningFilesystemSharedCache(); - /// Returns a cache entry for the corresponding key. - /// - /// A new cache entry is created if the key is not in the cache. This is a - /// thread safe call. - SharedFileSystemEntry &get(StringRef Key); + /// Returns shard for the given key. + CacheShard &getShardForFilename(StringRef Filename) const; + CacheShard &getShardForUID(llvm::sys::fs::UniqueID UID) const; private: - struct CacheShard { - std::mutex CacheLock; - llvm::StringMap<SharedFileSystemEntry, llvm::BumpPtrAllocator> Cache; - }; std::unique_ptr<CacheShard[]> CacheShards; unsigned NumShards; }; @@ -162,8 +216,20 @@ class DependencyScanningFilesystemLocalCache { llvm::StringMap<const CachedFileSystemEntry *, llvm::BumpPtrAllocator> Cache; public: - const CachedFileSystemEntry *getCachedEntry(StringRef Filename) { - return Cache[Filename]; + /// Returns entry associated with the filename or nullptr if none is found. + const CachedFileSystemEntry *findEntryByFilename(StringRef Filename) const { + auto It = Cache.find(Filename); + return It == Cache.end() ? nullptr : It->getValue(); + } + + /// Associates the given entry with the filename and returns the given entry + /// pointer (for convenience). + const CachedFileSystemEntry & + insertEntryForFilename(StringRef Filename, + const CachedFileSystemEntry &Entry) { + const auto *InsertedEntry = Cache.insert({Filename, &Entry}).first->second; + assert(InsertedEntry == &Entry && "entry already present"); + return *InsertedEntry; } }; @@ -176,26 +242,34 @@ class EntryRef { /// are minimized. bool Minimized; + /// The filename used to access this entry. + std::string Filename; + /// The underlying cached entry. const CachedFileSystemEntry &Entry; public: - EntryRef(bool Minimized, const CachedFileSystemEntry &Entry) - : Minimized(Minimized), Entry(Entry) {} - - llvm::ErrorOr<llvm::vfs::Status> getStatus() const { - auto MaybeStat = Entry.getStatus(); - if (!MaybeStat || MaybeStat->isDirectory()) - return MaybeStat; - return llvm::vfs::Status::copyWithNewSize(*MaybeStat, - getContents()->size()); + EntryRef(bool Minimized, StringRef Name, const CachedFileSystemEntry &Entry) + : Minimized(Minimized), Filename(Name), Entry(Entry) {} + + llvm::vfs::Status getStatus() const { + llvm::vfs::Status Stat = Entry.getStatus(); + if (!Stat.isDirectory()) + Stat = llvm::vfs::Status::copyWithNewSize(Stat, getContents().size()); + return llvm::vfs::Status::copyWithNewName(Stat, Filename); } + bool isError() const { return Entry.isError(); } bool isDirectory() const { return Entry.isDirectory(); } - StringRef getName() const { return Entry.getName(); } + /// If the cached entry represents an error, promotes it into `ErrorOr`. + llvm::ErrorOr<EntryRef> unwrapError() const { + if (isError()) + return Entry.getError(); + return *this; + } - llvm::ErrorOr<StringRef> getContents() const { + StringRef getContents() const { return Minimized ? Entry.getMinimizedContents() : Entry.getOriginalContents(); } @@ -234,9 +308,90 @@ public: private: /// Check whether the file should be minimized. - bool shouldMinimize(StringRef Filename); + bool shouldMinimize(StringRef Filename, llvm::sys::fs::UniqueID UID); + + /// Returns entry for the given filename. + /// + /// Attempts to use the local and shared caches first, then falls back to + /// using the underlying filesystem. + llvm::ErrorOr<EntryRef> + getOrCreateFileSystemEntry(StringRef Filename, + bool DisableMinimization = false); + + /// For a filename that's not yet associated with any entry in the caches, + /// uses the underlying filesystem to either look up the entry based in the + /// shared cache indexed by unique ID, or creates new entry from scratch. + llvm::ErrorOr<const CachedFileSystemEntry &> + computeAndStoreResult(StringRef Filename); + + /// Minimizes the given entry if necessary and returns a wrapper object with + /// reference semantics. + EntryRef minimizeIfNecessary(const CachedFileSystemEntry &Entry, + StringRef Filename, bool Disable); + + /// Represents a filesystem entry that has been stat-ed (and potentially read) + /// and that's about to be inserted into the cache as `CachedFileSystemEntry`. + struct TentativeEntry { + llvm::vfs::Status Status; + std::unique_ptr<llvm::MemoryBuffer> Contents; + + TentativeEntry(llvm::vfs::Status Status, + std::unique_ptr<llvm::MemoryBuffer> Contents = nullptr) + : Status(std::move(Status)), Contents(std::move(Contents)) {} + }; + + /// Reads file at the given path. Enforces consistency between the file size + /// in status and size of read contents. + llvm::ErrorOr<TentativeEntry> readFile(StringRef Filename); - llvm::ErrorOr<EntryRef> getOrCreateFileSystemEntry(StringRef Filename); + /// Returns entry associated with the unique ID of the given tentative entry + /// if there is some in the shared cache. Otherwise, constructs new one, + /// associates it with the unique ID and returns the result. + const CachedFileSystemEntry & + getOrEmplaceSharedEntryForUID(TentativeEntry TEntry); + + /// Returns entry associated with the filename or nullptr if none is found. + /// + /// Returns entry from local cache if there is some. Otherwise, if the entry + /// is found in the shared cache, writes it through the local cache and + /// returns it. Otherwise returns nullptr. + const CachedFileSystemEntry * + findEntryByFilenameWithWriteThrough(StringRef Filename); + + /// Returns entry associated with the unique ID in the shared cache or nullptr + /// if none is found. + const CachedFileSystemEntry * + findSharedEntryByUID(llvm::vfs::Status Stat) const { + return SharedCache.getShardForUID(Stat.getUniqueID()) + .findEntryByUID(Stat.getUniqueID()); + } + + /// Associates the given entry with the filename in the local cache and + /// returns it. + const CachedFileSystemEntry & + insertLocalEntryForFilename(StringRef Filename, + const CachedFileSystemEntry &Entry) { + return LocalCache.insertEntryForFilename(Filename, Entry); + } + + /// Returns entry associated with the filename in the shared cache if there is + /// some. Otherwise, constructs new one with the given error code, associates + /// it with the filename and returns the result. + const CachedFileSystemEntry & + getOrEmplaceSharedEntryForFilename(StringRef Filename, std::error_code EC) { + return SharedCache.getShardForFilename(Filename) + .getOrEmplaceEntryForFilename(Filename, EC); + } + + /// Returns entry associated with the filename in the shared cache if there is + /// some. Otherwise, associates the given entry with the filename and returns + /// it. + const CachedFileSystemEntry & + getOrInsertSharedEntryForFilename(StringRef Filename, + const CachedFileSystemEntry &Entry) { + return SharedCache.getShardForFilename(Filename) + .getOrInsertEntryForFilename(Filename, Entry); + } /// The global cache shared between worker threads. DependencyScanningFilesystemSharedCache &SharedCache; @@ -248,11 +403,11 @@ private: /// currently active preprocessor. ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings; /// The set of files that should not be minimized. - llvm::StringSet<> NotToBeMinimized; + llvm::DenseSet<llvm::sys::fs::UniqueID> NotToBeMinimized; }; } // end namespace dependencies } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_FILESYSTEM_H +#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H diff --git contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h index d58e736ab6a6..5c6dce611a95 100644 --- contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h +++ contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_SERVICE_H -#define LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_SERVICE_H +#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H +#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H #include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h" @@ -83,4 +83,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_SERVICE_H +#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H diff --git contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h index 9e2ff82f5614..2eb7a35b27b9 100644 --- contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_TOOL_H -#define LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_TOOL_H +#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H +#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" @@ -111,4 +111,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_TOOL_H +#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H diff --git contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h index 0f3a5369a021..b7631c09f275 100644 --- contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_WORKER_H -#define LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_WORKER_H +#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H +#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" @@ -91,4 +91,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_WORKER_H +#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H diff --git contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h index e61147d6f2b0..d1a7aab8c24b 100644 --- contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_MODULE_DEP_COLLECTOR_H -#define LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_MODULE_DEP_COLLECTOR_H +#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H +#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" @@ -234,4 +234,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_MODULE_DEP_COLLECTOR_H +#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H diff --git contrib/llvm-project/clang/include/clang/Tooling/FixIt.h contrib/llvm-project/clang/include/clang/Tooling/FixIt.h index 5fce71f2d8f7..1624c2d6be36 100644 --- contrib/llvm-project/clang/include/clang/Tooling/FixIt.h +++ contrib/llvm-project/clang/include/clang/Tooling/FixIt.h @@ -76,4 +76,4 @@ FixItHint createReplacement(const D &Destination, StringRef Source) { } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_FIXINT_H +#endif // LLVM_CLANG_TOOLING_FIXIT_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h index 239be36012c3..33dd386d2340 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H -#define LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H #include "clang/AST/ASTTypeTraits.h" #include "clang/AST/Stmt.h" @@ -152,4 +152,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_AST_SELECTION_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_ASTSELECTION_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/AtomicChange.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/AtomicChange.h index f1034a3d0579..3945a7c9fefb 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/AtomicChange.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/AtomicChange.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H -#define LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_ATOMICCHANGE_H +#define LLVM_CLANG_TOOLING_REFACTORING_ATOMICCHANGE_H #include "clang/Basic/SourceManager.h" #include "clang/Format/Format.h" @@ -187,4 +187,4 @@ applyAtomicChanges(llvm::StringRef FilePath, llvm::StringRef Code, } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_ATOMICCHANGE_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_ATOMICCHANGE_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/Extract.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/Extract.h index 930991328ca0..2f7c5bc9acff 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/Extract.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/Extract.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_EXTRACT_EXTRACT_H -#define LLVM_CLANG_TOOLING_REFACTOR_EXTRACT_EXTRACT_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_EXTRACT_H +#define LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_EXTRACT_H #include "clang/Tooling/Refactoring/ASTSelection.h" #include "clang/Tooling/Refactoring/RefactoringActionRules.h" @@ -49,4 +49,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_EXTRACT_EXTRACT_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_EXTRACT_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h index 034a0aaaf6db..be44518d4bce 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H -#define LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_SOURCEEXTRACTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_SOURCEEXTRACTION_H #include "clang/Basic/LLVM.h" @@ -48,4 +48,4 @@ private: } // end namespace tooling } // end namespace clang -#endif //LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_EXTRACT_SOURCEEXTRACTION_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Lookup.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Lookup.h index 448bc422c4e7..dcb40b7eee66 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Lookup.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Lookup.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_LOOKUP_H -#define LLVM_CLANG_TOOLING_REFACTOR_LOOKUP_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_LOOKUP_H +#define LLVM_CLANG_TOOLING_REFACTORING_LOOKUP_H #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" @@ -47,4 +47,4 @@ std::string replaceNestedName(const NestedNameSpecifier *Use, } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_LOOKUP_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_LOOKUP_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h index 63d46abc2034..6fb2decf8614 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h @@ -12,8 +12,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H -#define LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H +#define LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H #include "clang/AST/AST.h" #include "clang/AST/RecursiveASTVisitor.h" @@ -150,4 +150,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_RECURSIVESYMBOLVISITOR_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringAction.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringAction.h index d4294ddb2f66..b362f655965e 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringAction.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringAction.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_H -#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTION_H #include "clang/Basic/LLVM.h" #include "clang/Tooling/Refactoring/RefactoringActionRules.h" @@ -60,4 +60,4 @@ std::vector<std::unique_ptr<RefactoringAction>> createRefactoringActions(); } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTION_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRule.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRule.h index 57dffa945acc..388535a69b8b 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRule.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRule.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_H -#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULE_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULE_H #include "clang/Basic/LLVM.h" #include "llvm/ADT/Optional.h" @@ -69,4 +69,4 @@ public: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULE_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h index 6a6dd83731e9..49e4a0c149f1 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_REQUIREMENTS_H -#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_REQUIREMENTS_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULEREQUIREMENTS_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULEREQUIREMENTS_H #include "clang/Basic/LLVM.h" #include "clang/Tooling/Refactoring/ASTSelection.h" @@ -119,4 +119,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_REQUIREMENTS_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULEREQUIREMENTS_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRules.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRules.h index e9606fd6018e..86fcc6ad0a79 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRules.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRules.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_H -#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULES_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULES_H #include "clang/Tooling/Refactoring/RefactoringActionRule.h" #include "clang/Tooling/Refactoring/RefactoringActionRulesInternal.h" @@ -90,4 +90,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULES_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h index fb373fcf5029..e6ebaea5248a 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_INTERNAL_H -#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_INTERNAL_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULESINTERNAL_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULESINTERNAL_H #include "clang/Basic/LLVM.h" #include "clang/Tooling/Refactoring/RefactoringActionRule.h" @@ -154,4 +154,4 @@ createRefactoringActionRule(const RequirementTypes &... Requirements) { } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULES_INTERNAL_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULESINTERNAL_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOption.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOption.h index 659e02b48e5c..b022c5d61b03 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOption.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOption.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_H -#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTION_H #include "clang/Basic/LLVM.h" #include <memory> @@ -60,4 +60,4 @@ std::shared_ptr<OptionType> createRefactoringOption() { } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTION_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h index d58b11355a26..f9f85f6eeb82 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_VISITOR_H -#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_VISITOR_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONVISITOR_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONVISITOR_H #include "clang/Basic/LLVM.h" #include <type_traits> @@ -58,4 +58,4 @@ struct IsValidOptionType : internal::HasHandle<T>::Type {}; } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_VISITOR_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONVISITOR_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h index 84122b111ee1..1575a136b11c 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTIONS_H -#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTIONS_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONS_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONS_H #include "clang/Basic/LLVM.h" #include "clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h" @@ -54,4 +54,4 @@ public: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTIONS_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGOPTIONS_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h index 2035c02bc17a..016eff80ca7b 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RESULT_CONSUMER_H -#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RESULT_CONSUMER_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRESULTCONSUMER_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRESULTCONSUMER_H #include "clang/Basic/LLVM.h" #include "clang/Tooling/Refactoring/AtomicChange.h" @@ -48,4 +48,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RESULT_CONSUMER_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRESULTCONSUMER_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringRuleContext.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringRuleContext.h index e0da9469deb5..7d97f811f024 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringRuleContext.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringRuleContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RULE_CONTEXT_H -#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RULE_CONTEXT_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRULECONTEXT_H +#define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRULECONTEXT_H #include "clang/Basic/DiagnosticError.h" #include "clang/Basic/SourceManager.h" @@ -86,4 +86,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_RULE_CONTEXT_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGRULECONTEXT_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/RenamingAction.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/RenamingAction.h index b04bc3e2d202..43a8d56e4e71 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/RenamingAction.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/RenamingAction.h @@ -11,8 +11,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_RENAMING_ACTION_H -#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_RENAMING_ACTION_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_RENAMINGACTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_RENAMINGACTION_H #include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Refactoring/AtomicChange.h" @@ -23,7 +23,6 @@ namespace clang { class ASTConsumer; -class CompilerInstance; namespace tooling { @@ -120,4 +119,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_RENAMING_ACTION_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_RENAMINGACTION_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolName.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolName.h index 9131a4565da7..6c28d40f3679 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolName.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolName.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_NAME_H -#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_NAME_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLNAME_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLNAME_H #include "clang/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" @@ -45,4 +45,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_NAME_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLNAME_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h index c4bfaa9cc377..0ae023b8d4e4 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H -#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLOCCURRENCES_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLOCCURRENCES_H #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" @@ -88,4 +88,4 @@ using SymbolOccurrences = std::vector<SymbolOccurrence>; } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_SYMBOL_OCCURRENCES_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_SYMBOLOCCURRENCES_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFinder.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFinder.h index 30f7f0a0008c..a7ffa8556888 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFinder.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFinder.h @@ -12,8 +12,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDER_H -#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDER_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDER_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDER_H #include "clang/AST/AST.h" #include "clang/AST/ASTContext.h" @@ -46,4 +46,4 @@ std::string getUSRForDecl(const Decl *Decl); } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDER_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDER_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h index 726987d9d46a..e81b5c2345c9 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h @@ -11,8 +11,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDING_ACTION_H -#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDING_ACTION_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDINGACTION_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDINGACTION_H #include "clang/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" @@ -23,7 +23,6 @@ namespace clang { class ASTConsumer; class ASTContext; -class CompilerInstance; class NamedDecl; namespace tooling { @@ -64,4 +63,4 @@ private: } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDING_ACTION_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRFINDINGACTION_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h index 7a7dd76c4238..c3ffb4421e00 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h +++ contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h @@ -12,8 +12,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_LOC_FINDER_H -#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_LOC_FINDER_H +#ifndef LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRLOCFINDER_H +#define LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRLOCFINDER_H #include "clang/AST/AST.h" #include "clang/Tooling/Core/Replacement.h" @@ -49,4 +49,4 @@ SymbolOccurrences getOccurrencesOfUSRs(ArrayRef<std::string> USRs, } // end namespace tooling } // end namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_LOC_FINDER_H +#endif // LLVM_CLANG_TOOLING_REFACTORING_RENAME_USRLOCFINDER_H diff --git contrib/llvm-project/clang/include/clang/Tooling/ReplacementsYaml.h contrib/llvm-project/clang/include/clang/Tooling/ReplacementsYaml.h index 83e35d623255..838f87fd1978 100644 --- contrib/llvm-project/clang/include/clang/Tooling/ReplacementsYaml.h +++ contrib/llvm-project/clang/include/clang/Tooling/ReplacementsYaml.h @@ -30,8 +30,7 @@ template <> struct MappingTraits<clang::tooling::Replacement> { /// Helper to (de)serialize a Replacement since we don't have direct /// access to its data members. struct NormalizedReplacement { - NormalizedReplacement(const IO &) - : FilePath(""), Offset(0), Length(0), ReplacementText("") {} + NormalizedReplacement(const IO &) : Offset(0), Length(0) {} NormalizedReplacement(const IO &, const clang::tooling::Replacement &R) : FilePath(R.getFilePath()), Offset(R.getOffset()), diff --git contrib/llvm-project/clang/include/clang/Tooling/Syntax/BuildTree.h contrib/llvm-project/clang/include/clang/Tooling/Syntax/BuildTree.h index 3c8dd8ceed09..d6235797fd7a 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Syntax/BuildTree.h +++ contrib/llvm-project/clang/include/clang/Tooling/Syntax/BuildTree.h @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// // Functions to construct a syntax tree from an AST. //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_SYNTAX_TREE_H -#define LLVM_CLANG_TOOLING_SYNTAX_TREE_H +#ifndef LLVM_CLANG_TOOLING_SYNTAX_BUILDTREE_H +#define LLVM_CLANG_TOOLING_SYNTAX_BUILDTREE_H #include "clang/AST/Decl.h" #include "clang/Basic/TokenKinds.h" diff --git contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tree.h contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tree.h index b92e92305417..2063c6b7d82a 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tree.h +++ contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tree.h @@ -18,8 +18,8 @@ // This is still work in progress and highly experimental, we leave room for // ourselves to completely change the design and/or implementation. //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_SYNTAX_TREE_CASCADE_H -#define LLVM_CLANG_TOOLING_SYNTAX_TREE_CASCADE_H +#ifndef LLVM_CLANG_TOOLING_SYNTAX_TREE_H +#define LLVM_CLANG_TOOLING_SYNTAX_TREE_H #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" @@ -181,7 +181,10 @@ class Tree : public Node { ChildIteratorBase() = default; explicit ChildIteratorBase(NodeT *N) : N(N) {} - bool operator==(const DerivedT &O) const { return O.N == N; } + friend bool operator==(const DerivedT &LHS, const DerivedT &RHS) { + return LHS.N == RHS.N; + } + NodeT &operator*() const { return *N; } DerivedT &operator++() { N = N->getNextSibling(); @@ -269,14 +272,6 @@ private: Node *LastChild = nullptr; }; -// Provide missing non_const == const overload. -// iterator_facade_base requires == to be a member, but implicit conversions -// don't work on the LHS of a member operator. -inline bool operator==(const Tree::ConstChildIterator &A, - const Tree::ConstChildIterator &B) { - return A.operator==(B); -} - /// A list of Elements separated or terminated by a fixed token. /// /// This type models the following grammar construct: diff --git contrib/llvm-project/clang/include/clang/Tooling/Tooling.h contrib/llvm-project/clang/include/clang/Tooling/Tooling.h index c9c6a2ffb7b3..b36f58ad3046 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Tooling.h +++ contrib/llvm-project/clang/include/clang/Tooling/Tooling.h @@ -54,7 +54,6 @@ class CompilerInstance; class CompilerInvocation; class DiagnosticConsumer; class DiagnosticsEngine; -class SourceManager; namespace driver { diff --git contrib/llvm-project/clang/include/clang/Tooling/Transformer/MatchConsumer.h contrib/llvm-project/clang/include/clang/Tooling/Transformer/MatchConsumer.h index cb0a5f684b7d..fb57dabb0a6f 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Transformer/MatchConsumer.h +++ contrib/llvm-project/clang/include/clang/Tooling/Transformer/MatchConsumer.h @@ -12,8 +12,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_MATCH_CONSUMER_H_ -#define LLVM_CLANG_TOOLING_TRANSFORMER_MATCH_CONSUMER_H_ +#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_MATCHCONSUMER_H +#define LLVM_CLANG_TOOLING_TRANSFORMER_MATCHCONSUMER_H #include "clang/AST/ASTTypeTraits.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -100,4 +100,4 @@ llvm::Expected<T> MatchComputation<T>::eval( } } // namespace transformer } // namespace clang -#endif // LLVM_CLANG_TOOLING_TRANSFORMER_MATCH_CONSUMER_H_ +#endif // LLVM_CLANG_TOOLING_TRANSFORMER_MATCHCONSUMER_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Transformer/Parsing.h contrib/llvm-project/clang/include/clang/Tooling/Transformer/Parsing.h index b143f63d8ca8..177eca6a044d 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Transformer/Parsing.h +++ contrib/llvm-project/clang/include/clang/Tooling/Transformer/Parsing.h @@ -13,8 +13,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_PARSING_H_ -#define LLVM_CLANG_TOOLING_REFACTOR_PARSING_H_ +#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_PARSING_H +#define LLVM_CLANG_TOOLING_TRANSFORMER_PARSING_H #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Basic/SourceLocation.h" @@ -37,4 +37,4 @@ llvm::Expected<RangeSelector> parseRangeSelector(llvm::StringRef Input); } // namespace transformer } // namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_PARSING_H_ +#endif // LLVM_CLANG_TOOLING_TRANSFORMER_PARSING_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Transformer/RangeSelector.h contrib/llvm-project/clang/include/clang/Tooling/Transformer/RangeSelector.h index 38ec24efec65..1e288043f0a8 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Transformer/RangeSelector.h +++ contrib/llvm-project/clang/include/clang/Tooling/Transformer/RangeSelector.h @@ -12,8 +12,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_ -#define LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_ +#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_RANGESELECTOR_H +#define LLVM_CLANG_TOOLING_TRANSFORMER_RANGESELECTOR_H #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Basic/SourceLocation.h" @@ -105,4 +105,4 @@ RangeSelector expansion(RangeSelector S); } // namespace transformer } // namespace clang -#endif // LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_ +#endif // LLVM_CLANG_TOOLING_TRANSFORMER_RANGESELECTOR_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Transformer/RewriteRule.h contrib/llvm-project/clang/include/clang/Tooling/Transformer/RewriteRule.h index ac93db8446df..6b14861e92d7 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Transformer/RewriteRule.h +++ contrib/llvm-project/clang/include/clang/Tooling/Transformer/RewriteRule.h @@ -12,8 +12,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_REWRITE_RULE_H_ -#define LLVM_CLANG_TOOLING_TRANSFORMER_REWRITE_RULE_H_ +#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_REWRITERULE_H +#define LLVM_CLANG_TOOLING_TRANSFORMER_REWRITERULE_H #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -450,4 +450,4 @@ findSelectedCase(const ast_matchers::MatchFinder::MatchResult &Result, } // namespace transformer } // namespace clang -#endif // LLVM_CLANG_TOOLING_TRANSFORMER_REWRITE_RULE_H_ +#endif // LLVM_CLANG_TOOLING_TRANSFORMER_REWRITERULE_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCode.h contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCode.h index 2c7eb65371cf..16411b9c398d 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCode.h +++ contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCode.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_SOURCE_CODE_H -#define LLVM_CLANG_TOOLING_TRANSFORMER_SOURCE_CODE_H +#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H +#define LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H #include "clang/AST/ASTContext.h" #include "clang/Basic/SourceLocation.h" @@ -100,4 +100,4 @@ getRangeForEdit(const CharSourceRange &EditRange, const ASTContext &Context) { } } // namespace tooling } // namespace clang -#endif // LLVM_CLANG_TOOLING_TRANSFORMER_SOURCE_CODE_H +#endif // LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H diff --git contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCodeBuilders.h contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCodeBuilders.h index 6c79a7588f28..ab0eb71ef44e 100644 --- contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCodeBuilders.h +++ contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCodeBuilders.h @@ -11,8 +11,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_SOURCE_CODE_BUILDERS_H_ -#define LLVM_CLANG_TOOLING_TRANSFORMER_SOURCE_CODE_BUILDERS_H_ +#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODEBUILDERS_H +#define LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODEBUILDERS_H #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" @@ -43,6 +43,15 @@ inline bool needParensBeforeDotOrArrow(const Expr &E) { /// Determines whether printing this expression to the right of a unary operator /// requires a parentheses to preserve its meaning. bool needParensAfterUnaryOperator(const Expr &E); + +// Recognizes known types (and sugared versions thereof) that overload the `*` +// and `->` operator. Below is the list of currently included types, but it is +// subject to change: +// +// * std::unique_ptr, std::shared_ptr, std::weak_ptr, +// * std::optional, absl::optional, llvm::Optional, +// * absl::StatusOr, llvm::Expected. +bool isKnownPointerLikeType(QualType Ty, ASTContext &Context); /// @} /// \name Basic code-string generation utilities. @@ -69,6 +78,8 @@ llvm::Optional<std::string> buildAddressOf(const Expr &E, /// `x` becomes `x.` /// `*a` becomes `a->` /// `a+b` becomes `(a+b).` +/// +/// DEPRECATED. Use `buildAccess`. llvm::Optional<std::string> buildDot(const Expr &E, const ASTContext &Context); /// Adds an arrow to the end of the given expression, but adds parentheses @@ -77,10 +88,34 @@ llvm::Optional<std::string> buildDot(const Expr &E, const ASTContext &Context); /// `x` becomes `x->` /// `&a` becomes `a.` /// `a+b` becomes `(a+b)->` +/// +/// DEPRECATED. Use `buildAccess`. llvm::Optional<std::string> buildArrow(const Expr &E, const ASTContext &Context); + +/// Specifies how to classify pointer-like types -- like values or like pointers +/// -- with regard to generating member-access syntax. +enum class PLTClass : bool { + Value, + Pointer, +}; + +/// Adds an appropriate access operator (`.`, `->` or nothing, in the case of +/// implicit `this`) to the end of the given expression. Adds parentheses when +/// needed by the syntax and simplifies when possible. If `PLTypeClass` is +/// `Pointer`, for known pointer-like types (see `isKnownPointerLikeType`), +/// treats `operator->` and `operator*` like the built-in `->` and `*` +/// operators. +/// +/// `x` becomes `x->` or `x.`, depending on `E`'s type +/// `a+b` becomes `(a+b)->` or `(a+b).`, depending on `E`'s type +/// `&a` becomes `a.` +/// `*a` becomes `a->` +llvm::Optional<std::string> +buildAccess(const Expr &E, ASTContext &Context, + PLTClass Classification = PLTClass::Pointer); /// @} } // namespace tooling } // namespace clang -#endif // LLVM_CLANG_TOOLING_TRANSFORMER_SOURCE_CODE_BUILDERS_H_ +#endif // LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODEBUILDERS_H diff --git contrib/llvm-project/clang/lib/ARCMigrate/Internals.h contrib/llvm-project/clang/lib/ARCMigrate/Internals.h index ed0136e4867a..8b482738cc89 100644 --- contrib/llvm-project/clang/lib/ARCMigrate/Internals.h +++ contrib/llvm-project/clang/lib/ARCMigrate/Internals.h @@ -154,13 +154,11 @@ public: std::vector<SourceLocation> &ARCMTMacroLocs; Optional<bool> EnableCFBridgeFns; - MigrationPass(ASTContext &Ctx, LangOptions::GCMode OrigGCMode, - Sema &sema, TransformActions &TA, - const CapturedDiagList &capturedDiags, + MigrationPass(ASTContext &Ctx, LangOptions::GCMode OrigGCMode, Sema &sema, + TransformActions &TA, const CapturedDiagList &capturedDiags, std::vector<SourceLocation> &ARCMTMacroLocs) - : Ctx(Ctx), OrigGCMode(OrigGCMode), MigOptions(), - SemaRef(sema), TA(TA), CapturedDiags(capturedDiags), - ARCMTMacroLocs(ARCMTMacroLocs) { } + : Ctx(Ctx), OrigGCMode(OrigGCMode), SemaRef(sema), TA(TA), + CapturedDiags(capturedDiags), ARCMTMacroLocs(ARCMTMacroLocs) {} const CapturedDiagList &getDiags() const { return CapturedDiags; } diff --git contrib/llvm-project/clang/lib/ARCMigrate/TransAutoreleasePool.cpp contrib/llvm-project/clang/lib/ARCMigrate/TransAutoreleasePool.cpp index 393adcd85a3f..47587d81850a 100644 --- contrib/llvm-project/clang/lib/ARCMigrate/TransAutoreleasePool.cpp +++ contrib/llvm-project/clang/lib/ARCMigrate/TransAutoreleasePool.cpp @@ -229,8 +229,9 @@ private: bool IsFollowedBySimpleReturnStmt; SmallVector<ObjCMessageExpr *, 4> Releases; - PoolScope() : PoolVar(nullptr), CompoundParent(nullptr), Begin(), End(), - IsFollowedBySimpleReturnStmt(false) { } + PoolScope() + : PoolVar(nullptr), CompoundParent(nullptr), + IsFollowedBySimpleReturnStmt(false) {} SourceRange getIndentedRange() const { Stmt::child_iterator rangeS = Begin; diff --git contrib/llvm-project/clang/lib/ARCMigrate/Transforms.cpp contrib/llvm-project/clang/lib/ARCMigrate/Transforms.cpp index ca48160d9c85..a08b0d084bb6 100644 --- contrib/llvm-project/clang/lib/ARCMigrate/Transforms.cpp +++ contrib/llvm-project/clang/lib/ARCMigrate/Transforms.cpp @@ -417,7 +417,7 @@ bool MigrationContext::rewritePropertyAttribute(StringRef fromAttr, if (tok.is(tok::r_paren)) return false; - while (1) { + while (true) { if (tok.isNot(tok::raw_identifier)) return false; if (tok.getRawIdentifier() == fromAttr) { if (!toAttr.empty()) { diff --git contrib/llvm-project/clang/lib/AST/ASTContext.cpp contrib/llvm-project/clang/lib/AST/ASTContext.cpp index 701260881a93..a1d5673950e1 100644 --- contrib/llvm-project/clang/lib/AST/ASTContext.cpp +++ contrib/llvm-project/clang/lib/AST/ASTContext.cpp @@ -6147,6 +6147,376 @@ bool ASTContext::hasSameTemplateName(TemplateName X, TemplateName Y) { return X.getAsVoidPointer() == Y.getAsVoidPointer(); } +bool ASTContext::isSameTemplateParameter(NamedDecl *X, NamedDecl *Y) { + if (X->getKind() != Y->getKind()) + return false; + + if (auto *TX = dyn_cast<TemplateTypeParmDecl>(X)) { + auto *TY = cast<TemplateTypeParmDecl>(Y); + if (TX->isParameterPack() != TY->isParameterPack()) + return false; + if (TX->hasTypeConstraint() != TY->hasTypeConstraint()) + return false; + const TypeConstraint *TXTC = TX->getTypeConstraint(); + const TypeConstraint *TYTC = TY->getTypeConstraint(); + if (!TXTC != !TYTC) + return false; + if (TXTC && TYTC) { + auto *NCX = TXTC->getNamedConcept(); + auto *NCY = TYTC->getNamedConcept(); + if (!NCX || !NCY || !isSameEntity(NCX, NCY)) + return false; + if (TXTC->hasExplicitTemplateArgs() != TYTC->hasExplicitTemplateArgs()) + return false; + if (TXTC->hasExplicitTemplateArgs()) { + auto *TXTCArgs = TXTC->getTemplateArgsAsWritten(); + auto *TYTCArgs = TYTC->getTemplateArgsAsWritten(); + if (TXTCArgs->NumTemplateArgs != TYTCArgs->NumTemplateArgs) + return false; + llvm::FoldingSetNodeID XID, YID; + for (auto &ArgLoc : TXTCArgs->arguments()) + ArgLoc.getArgument().Profile(XID, X->getASTContext()); + for (auto &ArgLoc : TYTCArgs->arguments()) + ArgLoc.getArgument().Profile(YID, Y->getASTContext()); + if (XID != YID) + return false; + } + } + return true; + } + + if (auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) { + auto *TY = cast<NonTypeTemplateParmDecl>(Y); + return TX->isParameterPack() == TY->isParameterPack() && + TX->getASTContext().hasSameType(TX->getType(), TY->getType()); + } + + auto *TX = cast<TemplateTemplateParmDecl>(X); + auto *TY = cast<TemplateTemplateParmDecl>(Y); + return TX->isParameterPack() == TY->isParameterPack() && + isSameTemplateParameterList(TX->getTemplateParameters(), + TY->getTemplateParameters()); +} + +bool ASTContext::isSameTemplateParameterList(TemplateParameterList *X, + TemplateParameterList *Y) { + if (X->size() != Y->size()) + return false; + + for (unsigned I = 0, N = X->size(); I != N; ++I) + if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I))) + return false; + + const Expr *XRC = X->getRequiresClause(); + const Expr *YRC = Y->getRequiresClause(); + if (!XRC != !YRC) + return false; + if (XRC) { + llvm::FoldingSetNodeID XRCID, YRCID; + XRC->Profile(XRCID, *this, /*Canonical=*/true); + YRC->Profile(YRCID, *this, /*Canonical=*/true); + if (XRCID != YRCID) + return false; + } + + return true; +} + +static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) { + if (auto *NS = X->getAsNamespace()) + return NS; + if (auto *NAS = X->getAsNamespaceAlias()) + return NAS->getNamespace(); + return nullptr; +} + +static bool isSameQualifier(const NestedNameSpecifier *X, + const NestedNameSpecifier *Y) { + if (auto *NSX = getNamespace(X)) { + auto *NSY = getNamespace(Y); + if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl()) + return false; + } else if (X->getKind() != Y->getKind()) + return false; + + // FIXME: For namespaces and types, we're permitted to check that the entity + // is named via the same tokens. We should probably do so. + switch (X->getKind()) { + case NestedNameSpecifier::Identifier: + if (X->getAsIdentifier() != Y->getAsIdentifier()) + return false; + break; + case NestedNameSpecifier::Namespace: + case NestedNameSpecifier::NamespaceAlias: + // We've already checked that we named the same namespace. + break; + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + if (X->getAsType()->getCanonicalTypeInternal() != + Y->getAsType()->getCanonicalTypeInternal()) + return false; + break; + case NestedNameSpecifier::Global: + case NestedNameSpecifier::Super: + return true; + } + + // Recurse into earlier portion of NNS, if any. + auto *PX = X->getPrefix(); + auto *PY = Y->getPrefix(); + if (PX && PY) + return isSameQualifier(PX, PY); + return !PX && !PY; +} + +/// Determine whether the attributes we can overload on are identical for A and +/// B. Will ignore any overloadable attrs represented in the type of A and B. +static bool hasSameOverloadableAttrs(const FunctionDecl *A, + const FunctionDecl *B) { + // Note that pass_object_size attributes are represented in the function's + // ExtParameterInfo, so we don't need to check them here. + + llvm::FoldingSetNodeID Cand1ID, Cand2ID; + auto AEnableIfAttrs = A->specific_attrs<EnableIfAttr>(); + auto BEnableIfAttrs = B->specific_attrs<EnableIfAttr>(); + + for (auto Pair : zip_longest(AEnableIfAttrs, BEnableIfAttrs)) { + Optional<EnableIfAttr *> Cand1A = std::get<0>(Pair); + Optional<EnableIfAttr *> Cand2A = std::get<1>(Pair); + + // Return false if the number of enable_if attributes is different. + if (!Cand1A || !Cand2A) + return false; + + Cand1ID.clear(); + Cand2ID.clear(); + + (*Cand1A)->getCond()->Profile(Cand1ID, A->getASTContext(), true); + (*Cand2A)->getCond()->Profile(Cand2ID, B->getASTContext(), true); + + // Return false if any of the enable_if expressions of A and B are + // different. + if (Cand1ID != Cand2ID) + return false; + } + return true; +} + +bool ASTContext::isSameEntity(NamedDecl *X, NamedDecl *Y) { + if (X == Y) + return true; + + if (X->getDeclName() != Y->getDeclName()) + return false; + + // Must be in the same context. + // + // Note that we can't use DeclContext::Equals here, because the DeclContexts + // could be two different declarations of the same function. (We will fix the + // semantic DC to refer to the primary definition after merging.) + if (!declaresSameEntity(cast<Decl>(X->getDeclContext()->getRedeclContext()), + cast<Decl>(Y->getDeclContext()->getRedeclContext()))) + return false; + + // Two typedefs refer to the same entity if they have the same underlying + // type. + if (const auto *TypedefX = dyn_cast<TypedefNameDecl>(X)) + if (const auto *TypedefY = dyn_cast<TypedefNameDecl>(Y)) + return hasSameType(TypedefX->getUnderlyingType(), + TypedefY->getUnderlyingType()); + + // Must have the same kind. + if (X->getKind() != Y->getKind()) + return false; + + // Objective-C classes and protocols with the same name always match. + if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X)) + return true; + + if (isa<ClassTemplateSpecializationDecl>(X)) { + // No need to handle these here: we merge them when adding them to the + // template. + return false; + } + + // Compatible tags match. + if (const auto *TagX = dyn_cast<TagDecl>(X)) { + const auto *TagY = cast<TagDecl>(Y); + return (TagX->getTagKind() == TagY->getTagKind()) || + ((TagX->getTagKind() == TTK_Struct || + TagX->getTagKind() == TTK_Class || + TagX->getTagKind() == TTK_Interface) && + (TagY->getTagKind() == TTK_Struct || + TagY->getTagKind() == TTK_Class || + TagY->getTagKind() == TTK_Interface)); + } + + // Functions with the same type and linkage match. + // FIXME: This needs to cope with merging of prototyped/non-prototyped + // functions, etc. + if (const auto *FuncX = dyn_cast<FunctionDecl>(X)) { + const auto *FuncY = cast<FunctionDecl>(Y); + if (const auto *CtorX = dyn_cast<CXXConstructorDecl>(X)) { + const auto *CtorY = cast<CXXConstructorDecl>(Y); + if (CtorX->getInheritedConstructor() && + !isSameEntity(CtorX->getInheritedConstructor().getConstructor(), + CtorY->getInheritedConstructor().getConstructor())) + return false; + } + + if (FuncX->isMultiVersion() != FuncY->isMultiVersion()) + return false; + + // Multiversioned functions with different feature strings are represented + // as separate declarations. + if (FuncX->isMultiVersion()) { + const auto *TAX = FuncX->getAttr<TargetAttr>(); + const auto *TAY = FuncY->getAttr<TargetAttr>(); + assert(TAX && TAY && "Multiversion Function without target attribute"); + + if (TAX->getFeaturesStr() != TAY->getFeaturesStr()) + return false; + } + + const Expr *XRC = FuncX->getTrailingRequiresClause(); + const Expr *YRC = FuncY->getTrailingRequiresClause(); + if (!XRC != !YRC) + return false; + if (XRC) { + llvm::FoldingSetNodeID XRCID, YRCID; + XRC->Profile(XRCID, *this, /*Canonical=*/true); + YRC->Profile(YRCID, *this, /*Canonical=*/true); + if (XRCID != YRCID) + return false; + } + + auto GetTypeAsWritten = [](const FunctionDecl *FD) { + // Map to the first declaration that we've already merged into this one. + // The TSI of redeclarations might not match (due to calling conventions + // being inherited onto the type but not the TSI), but the TSI type of + // the first declaration of the function should match across modules. + FD = FD->getCanonicalDecl(); + return FD->getTypeSourceInfo() ? FD->getTypeSourceInfo()->getType() + : FD->getType(); + }; + QualType XT = GetTypeAsWritten(FuncX), YT = GetTypeAsWritten(FuncY); + if (!hasSameType(XT, YT)) { + // We can get functions with different types on the redecl chain in C++17 + // if they have differing exception specifications and at least one of + // the excpetion specs is unresolved. + auto *XFPT = XT->getAs<FunctionProtoType>(); + auto *YFPT = YT->getAs<FunctionProtoType>(); + if (getLangOpts().CPlusPlus17 && XFPT && YFPT && + (isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) || + isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) && + hasSameFunctionTypeIgnoringExceptionSpec(XT, YT)) + return true; + return false; + } + + return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() && + hasSameOverloadableAttrs(FuncX, FuncY); + } + + // Variables with the same type and linkage match. + if (const auto *VarX = dyn_cast<VarDecl>(X)) { + const auto *VarY = cast<VarDecl>(Y); + if (VarX->getLinkageInternal() == VarY->getLinkageInternal()) { + if (hasSameType(VarX->getType(), VarY->getType())) + return true; + + // We can get decls with different types on the redecl chain. Eg. + // template <typename T> struct S { static T Var[]; }; // #1 + // template <typename T> T S<T>::Var[sizeof(T)]; // #2 + // Only? happens when completing an incomplete array type. In this case + // when comparing #1 and #2 we should go through their element type. + const ArrayType *VarXTy = getAsArrayType(VarX->getType()); + const ArrayType *VarYTy = getAsArrayType(VarY->getType()); + if (!VarXTy || !VarYTy) + return false; + if (VarXTy->isIncompleteArrayType() || VarYTy->isIncompleteArrayType()) + return hasSameType(VarXTy->getElementType(), VarYTy->getElementType()); + } + return false; + } + + // Namespaces with the same name and inlinedness match. + if (const auto *NamespaceX = dyn_cast<NamespaceDecl>(X)) { + const auto *NamespaceY = cast<NamespaceDecl>(Y); + return NamespaceX->isInline() == NamespaceY->isInline(); + } + + // Identical template names and kinds match if their template parameter lists + // and patterns match. + if (const auto *TemplateX = dyn_cast<TemplateDecl>(X)) { + const auto *TemplateY = cast<TemplateDecl>(Y); + return isSameEntity(TemplateX->getTemplatedDecl(), + TemplateY->getTemplatedDecl()) && + isSameTemplateParameterList(TemplateX->getTemplateParameters(), + TemplateY->getTemplateParameters()); + } + + // Fields with the same name and the same type match. + if (const auto *FDX = dyn_cast<FieldDecl>(X)) { + const auto *FDY = cast<FieldDecl>(Y); + // FIXME: Also check the bitwidth is odr-equivalent, if any. + return hasSameType(FDX->getType(), FDY->getType()); + } + + // Indirect fields with the same target field match. + if (const auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) { + const auto *IFDY = cast<IndirectFieldDecl>(Y); + return IFDX->getAnonField()->getCanonicalDecl() == + IFDY->getAnonField()->getCanonicalDecl(); + } + + // Enumerators with the same name match. + if (isa<EnumConstantDecl>(X)) + // FIXME: Also check the value is odr-equivalent. + return true; + + // Using shadow declarations with the same target match. + if (const auto *USX = dyn_cast<UsingShadowDecl>(X)) { + const auto *USY = cast<UsingShadowDecl>(Y); + return USX->getTargetDecl() == USY->getTargetDecl(); + } + + // Using declarations with the same qualifier match. (We already know that + // the name matches.) + if (const auto *UX = dyn_cast<UsingDecl>(X)) { + const auto *UY = cast<UsingDecl>(Y); + return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && + UX->hasTypename() == UY->hasTypename() && + UX->isAccessDeclaration() == UY->isAccessDeclaration(); + } + if (const auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) { + const auto *UY = cast<UnresolvedUsingValueDecl>(Y); + return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && + UX->isAccessDeclaration() == UY->isAccessDeclaration(); + } + if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X)) { + return isSameQualifier( + UX->getQualifier(), + cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier()); + } + + // Using-pack declarations are only created by instantiation, and match if + // they're instantiated from matching UnresolvedUsing...Decls. + if (const auto *UX = dyn_cast<UsingPackDecl>(X)) { + return declaresSameEntity( + UX->getInstantiatedFromUsingDecl(), + cast<UsingPackDecl>(Y)->getInstantiatedFromUsingDecl()); + } + + // Namespace alias definitions with the same target match. + if (const auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) { + const auto *NAY = cast<NamespaceAliasDecl>(Y); + return NAX->getNamespace()->Equals(NAY->getNamespace()); + } + + return false; +} + TemplateArgument ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const { switch (Arg.getKind()) { @@ -8474,8 +8844,8 @@ static TypedefDecl *CreateHexagonBuiltinVaListDecl(const ASTContext *Context) { FieldDecl *Field = FieldDecl::Create( const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(), SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i], - /*TInfo=*/0, - /*BitWidth=*/0, + /*TInfo=*/nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); VaListTagDecl->addDecl(Field); @@ -9817,12 +10187,13 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, // designates the object or function denoted by the reference, and the // expression is an lvalue unless the reference is an rvalue reference and // the expression is a function call (possibly inside parentheses). - if (LangOpts.OpenMP && LHS->getAs<ReferenceType>() && - RHS->getAs<ReferenceType>() && LHS->getTypeClass() == RHS->getTypeClass()) - return mergeTypes(LHS->getAs<ReferenceType>()->getPointeeType(), - RHS->getAs<ReferenceType>()->getPointeeType(), + auto *LHSRefTy = LHS->getAs<ReferenceType>(); + auto *RHSRefTy = RHS->getAs<ReferenceType>(); + if (LangOpts.OpenMP && LHSRefTy && RHSRefTy && + LHS->getTypeClass() == RHS->getTypeClass()) + return mergeTypes(LHSRefTy->getPointeeType(), RHSRefTy->getPointeeType(), OfBlockPointer, Unqualified, BlockReturnType); - if (LHS->getAs<ReferenceType>() || RHS->getAs<ReferenceType>()) + if (LHSRefTy || RHSRefTy) return {}; if (Unqualified) { @@ -10309,7 +10680,7 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const { // For _BitInt, return an unsigned _BitInt with same width. if (const auto *EITy = T->getAs<BitIntType>()) - return getBitIntType(/*IsUnsigned=*/true, EITy->getNumBits()); + return getBitIntType(/*Unsigned=*/true, EITy->getNumBits()); // For enums, get the underlying integer type of the enum, and let the general // integer type signchanging code handle it. @@ -10377,7 +10748,7 @@ QualType ASTContext::getCorrespondingSignedType(QualType T) const { // For _BitInt, return a signed _BitInt with same width. if (const auto *EITy = T->getAs<BitIntType>()) - return getBitIntType(/*IsUnsigned=*/false, EITy->getNumBits()); + return getBitIntType(/*Unsigned=*/false, EITy->getNumBits()); // For enums, get the underlying integer type of the enum, and let the general // integer type signchanging code handle it. @@ -11572,6 +11943,15 @@ uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const { return getTargetInfo().getNullPointerValue(AS); } +unsigned ASTContext::getTargetAddressSpace(QualType T) const { + return T->isFunctionType() ? getTargetInfo().getProgramAddressSpace() + : getTargetAddressSpace(T.getQualifiers()); +} + +unsigned ASTContext::getTargetAddressSpace(Qualifiers Q) const { + return getTargetAddressSpace(Q.getAddressSpace()); +} + unsigned ASTContext::getTargetAddressSpace(LangAS AS) const { if (isTargetAddressSpace(AS)) return toTargetAddressSpace(AS); diff --git contrib/llvm-project/clang/lib/AST/ASTImporter.cpp contrib/llvm-project/clang/lib/AST/ASTImporter.cpp index 7f78da10e0b3..457465e87d93 100644 --- contrib/llvm-project/clang/lib/AST/ASTImporter.cpp +++ contrib/llvm-project/clang/lib/AST/ASTImporter.cpp @@ -8409,8 +8409,8 @@ Expected<TypeSourceInfo *> ASTImporter::Import(TypeSourceInfo *FromTSI) { // and destructed after it is created. The construction already performs the // import of the data. template <typename T> struct AttrArgImporter { - AttrArgImporter<T>(const AttrArgImporter<T> &) = delete; - AttrArgImporter<T>(AttrArgImporter<T> &&) = default; + AttrArgImporter(const AttrArgImporter<T> &) = delete; + AttrArgImporter(AttrArgImporter<T> &&) = default; AttrArgImporter<T> &operator=(const AttrArgImporter<T> &) = delete; AttrArgImporter<T> &operator=(AttrArgImporter<T> &&) = default; @@ -8429,8 +8429,8 @@ private: // is used by the attribute classes. This object should be created once for the // array data to be imported (the array size is not imported, just copied). template <typename T> struct AttrArgArrayImporter { - AttrArgArrayImporter<T>(const AttrArgArrayImporter<T> &) = delete; - AttrArgArrayImporter<T>(AttrArgArrayImporter<T> &&) = default; + AttrArgArrayImporter(const AttrArgArrayImporter<T> &) = delete; + AttrArgArrayImporter(AttrArgArrayImporter<T> &&) = default; AttrArgArrayImporter<T> &operator=(const AttrArgArrayImporter<T> &) = delete; AttrArgArrayImporter<T> &operator=(AttrArgArrayImporter<T> &&) = default; diff --git contrib/llvm-project/clang/lib/AST/AttrImpl.cpp contrib/llvm-project/clang/lib/AST/AttrImpl.cpp index c2f13cf63830..7b8acfcd92be 100644 --- contrib/llvm-project/clang/lib/AST/AttrImpl.cpp +++ contrib/llvm-project/clang/lib/AST/AttrImpl.cpp @@ -139,6 +139,13 @@ void OMPDeclareTargetDeclAttr::printPrettyPragma( OS << " device_type(" << ConvertDevTypeTyToStr(getDevType()) << ")"; if (getMapType() != MT_To) OS << ' ' << ConvertMapTypeTyToStr(getMapType()); + if (Expr *E = getIndirectExpr()) { + OS << " indirect("; + E->printPretty(OS, nullptr, Policy); + OS << ")"; + } else if (getIndirect()) { + OS << " indirect"; + } } llvm::Optional<OMPDeclareTargetDeclAttr *> diff --git contrib/llvm-project/clang/lib/AST/CXXABI.h contrib/llvm-project/clang/lib/AST/CXXABI.h index ca9424bcb7a4..9258a53fefeb 100644 --- contrib/llvm-project/clang/lib/AST/CXXABI.h +++ contrib/llvm-project/clang/lib/AST/CXXABI.h @@ -21,7 +21,6 @@ namespace clang { class ASTContext; class CXXConstructorDecl; class DeclaratorDecl; -class Expr; class MangleContext; class MangleNumberingContext; class MemberPointerType; diff --git contrib/llvm-project/clang/lib/AST/CommentLexer.cpp contrib/llvm-project/clang/lib/AST/CommentLexer.cpp index 93531c06192d..61ce8979f13f 100644 --- contrib/llvm-project/clang/lib/AST/CommentLexer.cpp +++ contrib/llvm-project/clang/lib/AST/CommentLexer.cpp @@ -94,31 +94,12 @@ void Lexer::skipLineStartingDecorations() { if (BufferPtr == CommentEnd) return; - switch (*BufferPtr) { - case ' ': - case '\t': - case '\f': - case '\v': { - const char *NewBufferPtr = BufferPtr; - NewBufferPtr++; - if (NewBufferPtr == CommentEnd) + const char *NewBufferPtr = BufferPtr; + while (isHorizontalWhitespace(*NewBufferPtr)) + if (++NewBufferPtr == CommentEnd) return; - - char C = *NewBufferPtr; - while (isHorizontalWhitespace(C)) { - NewBufferPtr++; - if (NewBufferPtr == CommentEnd) - return; - C = *NewBufferPtr; - } - if (C == '*') - BufferPtr = NewBufferPtr + 1; - break; - } - case '*': - BufferPtr++; - break; - } + if (*NewBufferPtr == '*') + BufferPtr = NewBufferPtr + 1; } namespace { @@ -289,6 +270,29 @@ void Lexer::formTokenWithChars(Token &Result, const char *TokEnd, BufferPtr = TokEnd; } +const char *Lexer::skipTextToken() { + const char *TokenPtr = BufferPtr; + assert(TokenPtr < CommentEnd); + StringRef TokStartSymbols = ParseCommands ? "\n\r\\@\"&<" : "\n\r"; + +again: + size_t End = + StringRef(TokenPtr, CommentEnd - TokenPtr).find_first_of(TokStartSymbols); + if (End == StringRef::npos) + return CommentEnd; + + // Doxygen doesn't recognize any commands in a one-line double quotation. + // If we don't find an ending quotation mark, we pretend it never began. + if (*(TokenPtr + End) == '\"') { + TokenPtr += End + 1; + End = StringRef(TokenPtr, CommentEnd - TokenPtr).find_first_of("\n\r\""); + if (End != StringRef::npos && *(TokenPtr + End) == '\"') + TokenPtr += End + 1; + goto again; + } + return TokenPtr + End; +} + void Lexer::lexCommentText(Token &T) { assert(CommentState == LCS_InsideBCPLComment || CommentState == LCS_InsideCComment); @@ -309,17 +313,8 @@ void Lexer::lexCommentText(Token &T) { skipLineStartingDecorations(); return; - default: { - StringRef TokStartSymbols = ParseCommands ? "\n\r\\@&<" : "\n\r"; - size_t End = StringRef(TokenPtr, CommentEnd - TokenPtr) - .find_first_of(TokStartSymbols); - if (End != StringRef::npos) - TokenPtr += End; - else - TokenPtr = CommentEnd; - formTextToken(T, TokenPtr); - return; - } + default: + return formTextToken(T, skipTextToken()); } }; diff --git contrib/llvm-project/clang/lib/AST/Decl.cpp contrib/llvm-project/clang/lib/AST/Decl.cpp index 94a644cbe8e5..e6ce5a80dacd 100644 --- contrib/llvm-project/clang/lib/AST/Decl.cpp +++ contrib/llvm-project/clang/lib/AST/Decl.cpp @@ -786,6 +786,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, // // Note that we don't want to make the variable non-external // because of this, but unique-external linkage suits us. + if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var) && !IgnoreVarTypeLinkage) { LinkageInfo TypeLV = getLVForType(*Var->getType(), computation); @@ -912,10 +913,6 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, if (!isExternallyVisible(LV.getLinkage())) return LinkageInfo(LV.getLinkage(), DefaultVisibility, false); - // Mark the symbols as hidden when compiling for the device. - if (Context.getLangOpts().OpenMP && Context.getLangOpts().OpenMPIsDevice) - LV.mergeVisibility(HiddenVisibility, /*newExplicit=*/false); - return LV; } @@ -1069,6 +1066,7 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D, // Finally, merge in information from the class. LV.mergeMaybeWithVisibility(classLV, considerClassVisibility); + return LV; } @@ -3236,7 +3234,6 @@ bool FunctionDecl::isGlobal() const { if (const auto *Namespace = cast<NamespaceDecl>(DC)) { if (!Namespace->getDeclName()) return false; - break; } } diff --git contrib/llvm-project/clang/lib/AST/DeclBase.cpp contrib/llvm-project/clang/lib/AST/DeclBase.cpp index 064012ba865c..9ee1cc083086 100644 --- contrib/llvm-project/clang/lib/AST/DeclBase.cpp +++ contrib/llvm-project/clang/lib/AST/DeclBase.cpp @@ -995,6 +995,15 @@ bool Decl::AccessDeclContextCheck() const { return true; } +bool Decl::isInExportDeclContext() const { + const DeclContext *DC = getLexicalDeclContext(); + + while (DC && !isa<ExportDecl>(DC)) + DC = DC->getLexicalParent(); + + return DC && isa<ExportDecl>(DC); +} + static Decl::Kind getKind(const Decl *D) { return D->getKind(); } static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); } @@ -1212,7 +1221,8 @@ bool DeclContext::Encloses(const DeclContext *DC) const { return getPrimaryContext()->Encloses(DC); for (; DC; DC = DC->getParent()) - if (!isa<LinkageSpecDecl>(DC) && DC->getPrimaryContext() == this) + if (!isa<LinkageSpecDecl>(DC) && !isa<ExportDecl>(DC) && + DC->getPrimaryContext() == this) return true; return false; } @@ -1643,9 +1653,9 @@ void DeclContext::buildLookupImpl(DeclContext *DCtx, bool Internal) { DeclContext::lookup_result DeclContext::lookup(DeclarationName Name) const { - assert(getDeclKind() != Decl::LinkageSpec && - getDeclKind() != Decl::Export && - "should not perform lookups into transparent contexts"); + // For transparent DeclContext, we should lookup in their enclosing context. + if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export) + return getParent()->lookup(Name); const DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) diff --git contrib/llvm-project/clang/lib/AST/DeclCXX.cpp contrib/llvm-project/clang/lib/AST/DeclCXX.cpp index 1780358cc348..0cf6e60b2a6c 100644 --- contrib/llvm-project/clang/lib/AST/DeclCXX.cpp +++ contrib/llvm-project/clang/lib/AST/DeclCXX.cpp @@ -79,10 +79,9 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) HasBasesWithFields(false), HasBasesWithNonStaticDataMembers(false), HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false), HasMutableFields(false), HasVariantMembers(false), - HasOnlyCMembers(true), HasInClassInitializer(false), + HasOnlyCMembers(true), HasInitMethod(false), HasInClassInitializer(false), HasUninitializedReferenceMember(false), HasUninitializedFields(false), - HasInheritedConstructor(false), - HasInheritedDefaultConstructor(false), + HasInheritedConstructor(false), HasInheritedDefaultConstructor(false), HasInheritedAssignment(false), NeedOverloadResolutionForCopyConstructor(false), NeedOverloadResolutionForMoveConstructor(false), @@ -3272,7 +3271,7 @@ void MSGuidDecl::anchor() {} MSGuidDecl::MSGuidDecl(DeclContext *DC, QualType T, Parts P) : ValueDecl(Decl::MSGuid, DC, SourceLocation(), DeclarationName(), T), - PartVal(P), APVal() {} + PartVal(P) {} MSGuidDecl *MSGuidDecl::Create(const ASTContext &C, QualType T, Parts P) { DeclContext *DC = C.getTranslationUnitDecl(); diff --git contrib/llvm-project/clang/lib/AST/DeclObjC.cpp contrib/llvm-project/clang/lib/AST/DeclObjC.cpp index ba827a79c022..f15dd78929e2 100644 --- contrib/llvm-project/clang/lib/AST/DeclObjC.cpp +++ contrib/llvm-project/clang/lib/AST/DeclObjC.cpp @@ -232,6 +232,18 @@ ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const { return &Ctx.Idents.get(ivarName.str()); } +ObjCPropertyDecl *ObjCContainerDecl::getProperty(const IdentifierInfo *Id, + bool IsInstance) const { + for (auto *LookupResult : lookup(Id)) { + if (auto *Prop = dyn_cast<ObjCPropertyDecl>(LookupResult)) { + if (Prop->isInstanceProperty() == IsInstance) { + return Prop; + } + } + } + return nullptr; +} + /// FindPropertyDeclaration - Finds declaration of the property given its name /// in 'PropertyId' and returns it. It returns 0, if not found. ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration( diff --git contrib/llvm-project/clang/lib/AST/DeclPrinter.cpp contrib/llvm-project/clang/lib/AST/DeclPrinter.cpp index 044eb8f8f8e5..c3f1d1544f79 100644 --- contrib/llvm-project/clang/lib/AST/DeclPrinter.cpp +++ contrib/llvm-project/clang/lib/AST/DeclPrinter.cpp @@ -588,7 +588,7 @@ static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out, } EOut << " "; EOut.flush(); - Out << EOut.str(); + Out << Proto; } void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { @@ -731,7 +731,6 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { FT->getNoexceptExpr()->printPretty(EOut, nullptr, SubPolicy, Indentation, "\n", &Context); EOut.flush(); - Proto += EOut.str(); Proto += ")"; } } @@ -885,7 +884,10 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { } } - printDeclType(T, D->getName()); + printDeclType(T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters && + D->getIdentifier()) + ? D->getIdentifier()->deuglifiedName() + : D->getName()); Expr *Init = D->getInit(); if (!Policy.SuppressInitializers && Init) { bool ImplicitInit = false; @@ -1131,8 +1133,12 @@ void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) { else if (TTP->getDeclName()) Out << ' '; - if (TTP->getDeclName()) - Out << TTP->getDeclName(); + if (TTP->getDeclName()) { + if (Policy.CleanUglifiedParameters && TTP->getIdentifier()) + Out << TTP->getIdentifier()->deuglifiedName(); + else + Out << TTP->getDeclName(); + } } else if (auto *TD = D->getTemplatedDecl()) Visit(TD); else if (const auto *Concept = dyn_cast<ConceptDecl>(D)) { @@ -1742,8 +1748,12 @@ void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) { else if (TTP->getDeclName()) Out << ' '; - if (TTP->getDeclName()) - Out << TTP->getDeclName(); + if (TTP->getDeclName()) { + if (Policy.CleanUglifiedParameters && TTP->getIdentifier()) + Out << TTP->getIdentifier()->deuglifiedName(); + else + Out << TTP->getDeclName(); + } if (TTP->hasDefaultArgument()) { Out << " = "; @@ -1755,7 +1765,8 @@ void DeclPrinter::VisitNonTypeTemplateParmDecl( const NonTypeTemplateParmDecl *NTTP) { StringRef Name; if (IdentifierInfo *II = NTTP->getIdentifier()) - Name = II->getName(); + Name = + Policy.CleanUglifiedParameters ? II->deuglifiedName() : II->getName(); printDeclType(NTTP->getType(), Name, NTTP->isParameterPack()); if (NTTP->hasDefaultArgument()) { diff --git contrib/llvm-project/clang/lib/AST/Expr.cpp contrib/llvm-project/clang/lib/AST/Expr.cpp index 2530beb89d17..45e94847caee 100644 --- contrib/llvm-project/clang/lib/AST/Expr.cpp +++ contrib/llvm-project/clang/lib/AST/Expr.cpp @@ -1281,7 +1281,7 @@ StringLiteral::getLocationOfByte(unsigned ByteNo, const SourceManager &SM, StringOffset = *StartTokenByteOffset; ByteNo -= StringOffset; } - while (1) { + while (true) { assert(TokNo < getNumConcatenated() && "Invalid byte number!"); SourceLocation StrTokLoc = getStrTokenLoc(TokNo); diff --git contrib/llvm-project/clang/lib/AST/ExprConcepts.cpp contrib/llvm-project/clang/lib/AST/ExprConcepts.cpp index 8cb8625e2a1a..c17453fb45fb 100644 --- contrib/llvm-project/clang/lib/AST/ExprConcepts.cpp +++ contrib/llvm-project/clang/lib/AST/ExprConcepts.cpp @@ -57,9 +57,9 @@ ConceptSpecializationExpr::ConceptSpecializationExpr( } ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty, - unsigned NumTemplateArgs) - : Expr(ConceptSpecializationExprClass, Empty), ConceptReference(), - NumTemplateArgs(NumTemplateArgs) { } + unsigned NumTemplateArgs) + : Expr(ConceptSpecializationExprClass, Empty), + NumTemplateArgs(NumTemplateArgs) {} void ConceptSpecializationExpr::setTemplateArguments( ArrayRef<TemplateArgument> Converted) { diff --git contrib/llvm-project/clang/lib/AST/ExprConstant.cpp contrib/llvm-project/clang/lib/AST/ExprConstant.cpp index 6f979d3264bb..40d0bd44b5d9 100644 --- contrib/llvm-project/clang/lib/AST/ExprConstant.cpp +++ contrib/llvm-project/clang/lib/AST/ExprConstant.cpp @@ -1706,8 +1706,8 @@ namespace { struct MemberPtr { MemberPtr() {} - explicit MemberPtr(const ValueDecl *Decl) : - DeclAndIsDerivedMember(Decl, false), Path() {} + explicit MemberPtr(const ValueDecl *Decl) + : DeclAndIsDerivedMember(Decl, false) {} /// The member or (direct or indirect) field referred to by this member /// pointer, or 0 if this is a null member pointer. @@ -4936,8 +4936,13 @@ static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, if (SS->getConditionVariable() && !EvaluateDecl(Info, SS->getConditionVariable())) return ESR_Failed; - if (!EvaluateInteger(SS->getCond(), Value, Info)) - return ESR_Failed; + if (SS->getCond()->isValueDependent()) { + if (!EvaluateDependentExpr(SS->getCond(), Info)) + return ESR_Failed; + } else { + if (!EvaluateInteger(SS->getCond(), Value, Info)) + return ESR_Failed; + } if (!CondScope.destroy()) return ESR_Failed; } @@ -6040,7 +6045,7 @@ static bool EvaluateArgs(ArrayRef<const Expr *> Args, CallRef Call, unsigned ASTIdx = Idx.getASTIndex(); if (ASTIdx >= Args.size()) continue; - ForbiddenNullArgs[ASTIdx] = 1; + ForbiddenNullArgs[ASTIdx] = true; } } } @@ -10437,6 +10442,15 @@ bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { if (!Evaluate(SubExprValue, Info, SubExpr)) return false; + // FIXME: This vector evaluator someday needs to be changed to be LValue + // aware/keep LValue information around, rather than dealing with just vector + // types directly. Until then, we cannot handle cases where the operand to + // these unary operators is an LValue. The only case I've been able to see + // cause this is operator++ assigning to a member expression (only valid in + // altivec compilations) in C mode, so this shouldn't limit us too much. + if (SubExprValue.isLValue()) + return false; + assert(SubExprValue.getVectorLength() == VD->getNumElements() && "Vector length doesn't match type?"); @@ -10683,28 +10697,55 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, bool HadZeroInit = Value->hasValue(); if (const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(Type)) { - unsigned N = CAT->getSize().getZExtValue(); + unsigned FinalSize = CAT->getSize().getZExtValue(); // Preserve the array filler if we had prior zero-initialization. APValue Filler = HadZeroInit && Value->hasArrayFiller() ? Value->getArrayFiller() : APValue(); - *Value = APValue(APValue::UninitArray(), N, N); - - if (HadZeroInit) - for (unsigned I = 0; I != N; ++I) - Value->getArrayInitializedElt(I) = Filler; + *Value = APValue(APValue::UninitArray(), 0, FinalSize); + if (FinalSize == 0) + return true; - // Initialize the elements. LValue ArrayElt = Subobject; ArrayElt.addArray(Info, E, CAT); - for (unsigned I = 0; I != N; ++I) - if (!VisitCXXConstructExpr(E, ArrayElt, &Value->getArrayInitializedElt(I), - CAT->getElementType()) || - !HandleLValueArrayAdjustment(Info, E, ArrayElt, CAT->getElementType(), - 1)) - return false; + // We do the whole initialization in two passes, first for just one element, + // then for the whole array. It's possible we may find out we can't do const + // init in the first pass, in which case we avoid allocating a potentially + // large array. We don't do more passes because expanding array requires + // copying the data, which is wasteful. + for (const unsigned N : {1u, FinalSize}) { + unsigned OldElts = Value->getArrayInitializedElts(); + if (OldElts == N) + break; + + // Expand the array to appropriate size. + APValue NewValue(APValue::UninitArray(), N, FinalSize); + for (unsigned I = 0; I < OldElts; ++I) + NewValue.getArrayInitializedElt(I).swap( + Value->getArrayInitializedElt(I)); + Value->swap(NewValue); + + if (HadZeroInit) + for (unsigned I = OldElts; I < N; ++I) + Value->getArrayInitializedElt(I) = Filler; + + // Initialize the elements. + for (unsigned I = OldElts; I < N; ++I) { + if (!VisitCXXConstructExpr(E, ArrayElt, + &Value->getArrayInitializedElt(I), + CAT->getElementType()) || + !HandleLValueArrayAdjustment(Info, E, ArrayElt, + CAT->getElementType(), 1)) + return false; + // When checking for const initilization any diagnostic is considered + // an error. + if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && + !Info.keepEvaluatingAfterFailure()) + return false; + } + } return true; } diff --git contrib/llvm-project/clang/lib/AST/FormatString.cpp contrib/llvm-project/clang/lib/AST/FormatString.cpp index 83b952116a5e..102bcca96a38 100644 --- contrib/llvm-project/clang/lib/AST/FormatString.cpp +++ contrib/llvm-project/clang/lib/AST/FormatString.cpp @@ -21,7 +21,6 @@ using clang::analyze_format_string::FormatStringHandler; using clang::analyze_format_string::FormatSpecifier; using clang::analyze_format_string::LengthModifier; using clang::analyze_format_string::OptionalAmount; -using clang::analyze_format_string::PositionContext; using clang::analyze_format_string::ConversionSpecifier; using namespace clang; diff --git contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 5c8cb4274260..da538aa332ff 100644 --- contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -207,13 +207,13 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) { template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) { - OptionScope<Emitter> Scope(this, /*discardResult=*/true); + OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true); return this->Visit(E); } template <class Emitter> bool ByteCodeExprGen<Emitter>::visit(const Expr *E) { - OptionScope<Emitter> Scope(this, /*discardResult=*/false); + OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false); return this->Visit(E); } diff --git contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.h contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.h index 716f28551e58..124a6ff03f18 100644 --- contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.h +++ contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -28,8 +28,6 @@ namespace clang { class QualType; namespace interp { -class Function; -class State; template <class Emitter> class LocalScope; template <class Emitter> class RecordScope; diff --git contrib/llvm-project/clang/lib/AST/Interp/ByteCodeStmtGen.h contrib/llvm-project/clang/lib/AST/Interp/ByteCodeStmtGen.h index d9c0b64ed4b8..3bc665b84b4d 100644 --- contrib/llvm-project/clang/lib/AST/Interp/ByteCodeStmtGen.h +++ contrib/llvm-project/clang/lib/AST/Interp/ByteCodeStmtGen.h @@ -25,11 +25,7 @@ #include "llvm/ADT/Optional.h" namespace clang { -class QualType; - namespace interp { -class Function; -class State; template <class Emitter> class LoopScope; template <class Emitter> class SwitchScope; diff --git contrib/llvm-project/clang/lib/AST/Interp/Context.h contrib/llvm-project/clang/lib/AST/Interp/Context.h index 4f25ff977b81..0627d9fb14f5 100644 --- contrib/llvm-project/clang/lib/AST/Interp/Context.h +++ contrib/llvm-project/clang/lib/AST/Interp/Context.h @@ -23,7 +23,6 @@ namespace clang { class ASTContext; class LangOptions; -class Stmt; class FunctionDecl; class VarDecl; diff --git contrib/llvm-project/clang/lib/AST/Interp/InterpBlock.h contrib/llvm-project/clang/lib/AST/Interp/InterpBlock.h index 0ccdef221c83..2d5386e60b8c 100644 --- contrib/llvm-project/clang/lib/AST/Interp/InterpBlock.h +++ contrib/llvm-project/clang/lib/AST/Interp/InterpBlock.h @@ -25,10 +25,8 @@ namespace clang { namespace interp { class Block; class DeadBlock; -class Context; class InterpState; class Pointer; -class Function; enum PrimType : unsigned; /// A memory block, either on the stack or in the heap. diff --git contrib/llvm-project/clang/lib/AST/Interp/Pointer.h contrib/llvm-project/clang/lib/AST/Interp/Pointer.h index f2f6e0e76018..587531aec82a 100644 --- contrib/llvm-project/clang/lib/AST/Interp/Pointer.h +++ contrib/llvm-project/clang/lib/AST/Interp/Pointer.h @@ -26,10 +26,7 @@ namespace clang { namespace interp { class Block; class DeadBlock; -class Context; -class InterpState; class Pointer; -class Function; enum PrimType : unsigned; /// A pointer to a memory block, live or dead. diff --git contrib/llvm-project/clang/lib/AST/Interp/PrimType.h contrib/llvm-project/clang/lib/AST/Interp/PrimType.h index f5f4f8e5c32d..de4bf9bf802e 100644 --- contrib/llvm-project/clang/lib/AST/Interp/PrimType.h +++ contrib/llvm-project/clang/lib/AST/Interp/PrimType.h @@ -81,35 +81,27 @@ inline bool isPrimitiveIntegral(PrimType Type) { /// Helper macro to simplify type switches. /// The macro implicitly exposes a type T in the scope of the inner block. #define TYPE_SWITCH_CASE(Name, B) \ - case Name: { using T = PrimConv<Name>::T; do {B;} while(0); break; } + case Name: { using T = PrimConv<Name>::T; B; break; } #define TYPE_SWITCH(Expr, B) \ - switch (Expr) { \ - TYPE_SWITCH_CASE(PT_Sint8, B) \ - TYPE_SWITCH_CASE(PT_Uint8, B) \ - TYPE_SWITCH_CASE(PT_Sint16, B) \ - TYPE_SWITCH_CASE(PT_Uint16, B) \ - TYPE_SWITCH_CASE(PT_Sint32, B) \ - TYPE_SWITCH_CASE(PT_Uint32, B) \ - TYPE_SWITCH_CASE(PT_Sint64, B) \ - TYPE_SWITCH_CASE(PT_Uint64, B) \ - TYPE_SWITCH_CASE(PT_Bool, B) \ - TYPE_SWITCH_CASE(PT_Ptr, B) \ - } + do { \ + switch (Expr) { \ + TYPE_SWITCH_CASE(PT_Sint8, B) \ + TYPE_SWITCH_CASE(PT_Uint8, B) \ + TYPE_SWITCH_CASE(PT_Sint16, B) \ + TYPE_SWITCH_CASE(PT_Uint16, B) \ + TYPE_SWITCH_CASE(PT_Sint32, B) \ + TYPE_SWITCH_CASE(PT_Uint32, B) \ + TYPE_SWITCH_CASE(PT_Sint64, B) \ + TYPE_SWITCH_CASE(PT_Uint64, B) \ + TYPE_SWITCH_CASE(PT_Bool, B) \ + TYPE_SWITCH_CASE(PT_Ptr, B) \ + } \ + } while (0) #define COMPOSITE_TYPE_SWITCH(Expr, B, D) \ - switch (Expr) { \ - TYPE_SWITCH_CASE(PT_Ptr, B) \ - default: do { D; } while(0); break; \ - } -#define INT_TYPE_SWITCH(Expr, B) \ - switch (Expr) { \ - TYPE_SWITCH_CASE(PT_Sint8, B) \ - TYPE_SWITCH_CASE(PT_Uint8, B) \ - TYPE_SWITCH_CASE(PT_Sint16, B) \ - TYPE_SWITCH_CASE(PT_Uint16, B) \ - TYPE_SWITCH_CASE(PT_Sint32, B) \ - TYPE_SWITCH_CASE(PT_Uint32, B) \ - TYPE_SWITCH_CASE(PT_Sint64, B) \ - TYPE_SWITCH_CASE(PT_Uint64, B) \ - default: llvm_unreachable("not an integer"); \ - } + do { \ + switch (Expr) { \ + TYPE_SWITCH_CASE(PT_Ptr, B) \ + default: { D; break; } \ + } \ + } while (0) #endif diff --git contrib/llvm-project/clang/lib/AST/Interp/Program.h contrib/llvm-project/clang/lib/AST/Interp/Program.h index c81ec777a5fe..ca985af8ad30 100644 --- contrib/llvm-project/clang/lib/AST/Interp/Program.h +++ contrib/llvm-project/clang/lib/AST/Interp/Program.h @@ -29,15 +29,12 @@ namespace clang { class RecordDecl; class Expr; class FunctionDecl; -class Stmt; class StringLiteral; class VarDecl; namespace interp { class Context; -class State; class Record; -class Scope; /// The program contains and links the bytecode for all functions. class Program { diff --git contrib/llvm-project/clang/lib/AST/ItaniumMangle.cpp contrib/llvm-project/clang/lib/AST/ItaniumMangle.cpp index 7afc1250a36f..2e734e2b28cd 100644 --- contrib/llvm-project/clang/lib/AST/ItaniumMangle.cpp +++ contrib/llvm-project/clang/lib/AST/ItaniumMangle.cpp @@ -659,8 +659,7 @@ bool ItaniumMangleContextImpl::isUniqueInternalLinkageDecl( } bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) { - const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); - if (FD) { + if (const auto *FD = dyn_cast<FunctionDecl>(D)) { LanguageLinkage L = FD->getLanguageLinkage(); // Overloadable functions need mangling. if (FD->hasAttr<OverloadableAttr>()) @@ -696,21 +695,24 @@ bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) { if (!getASTContext().getLangOpts().CPlusPlus) return false; - const VarDecl *VD = dyn_cast<VarDecl>(D); - if (VD && !isa<DecompositionDecl>(D)) { + if (const auto *VD = dyn_cast<VarDecl>(D)) { + // Decompositions are mangled. + if (isa<DecompositionDecl>(VD)) + return true; + // C variables are not mangled. if (VD->isExternC()) return false; - // Variables at global scope with non-internal linkage are not mangled + // Variables at global scope with non-internal linkage are not mangled. const DeclContext *DC = getEffectiveDeclContext(D); // Check for extern variable declared locally. if (DC->isFunctionOrMethod() && D->hasLinkage()) - while (!DC->isNamespace() && !DC->isTranslationUnit()) + while (!DC->isFileContext()) DC = getEffectiveParentContext(DC); if (DC->isTranslationUnit() && D->getFormalLinkage() != InternalLinkage && !CXXNameMangler::shouldHaveAbiTags(*this, VD) && - !isa<VarTemplateSpecializationDecl>(D)) + !isa<VarTemplateSpecializationDecl>(VD)) return false; } @@ -5889,9 +5891,11 @@ void CXXNameMangler::mangleTemplateParameter(unsigned Depth, unsigned Index) { } void CXXNameMangler::mangleSeqID(unsigned SeqID) { - if (SeqID == 1) + if (SeqID == 0) { + // Nothing. + } else if (SeqID == 1) { Out << '0'; - else if (SeqID > 1) { + } else { SeqID--; // <seq-id> is encoded in base-36, using digits and upper case letters. diff --git contrib/llvm-project/clang/lib/AST/Mangle.cpp contrib/llvm-project/clang/lib/AST/Mangle.cpp index 54dbf484f377..984da9909ce2 100644 --- contrib/llvm-project/clang/lib/AST/Mangle.cpp +++ contrib/llvm-project/clang/lib/AST/Mangle.cpp @@ -225,11 +225,17 @@ void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) { if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) if (!MD->isStatic()) ++ArgWords; - for (const auto &AT : Proto->param_types()) + for (const auto &AT : Proto->param_types()) { + // If an argument type is incomplete there is no way to get its size to + // correctly encode into the mangling scheme. + // Follow GCCs behaviour by simply breaking out of the loop. + if (AT->isIncompleteType()) + break; // Size should be aligned to pointer size. ArgWords += llvm::alignTo(ASTContext.getTypeSize(AT), TI.getPointerWidth(0)) / TI.getPointerWidth(0); + } Out << ((TI.getPointerWidth(0) / 8) * ArgWords); } diff --git contrib/llvm-project/clang/lib/AST/MicrosoftCXXABI.cpp contrib/llvm-project/clang/lib/AST/MicrosoftCXXABI.cpp index 53d7e0b042ff..b7dc0e62e66a 100644 --- contrib/llvm-project/clang/lib/AST/MicrosoftCXXABI.cpp +++ contrib/llvm-project/clang/lib/AST/MicrosoftCXXABI.cpp @@ -36,8 +36,8 @@ class MicrosoftNumberingContext : public MangleNumberingContext { public: MicrosoftNumberingContext() - : MangleNumberingContext(), LambdaManglingNumber(0), - StaticLocalNumber(0), StaticThreadlocalNumber(0) {} + : LambdaManglingNumber(0), StaticLocalNumber(0), + StaticThreadlocalNumber(0) {} unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { return ++LambdaManglingNumber; diff --git contrib/llvm-project/clang/lib/AST/OSLog.cpp contrib/llvm-project/clang/lib/AST/OSLog.cpp index 094c0102854b..4cc5def0651f 100644 --- contrib/llvm-project/clang/lib/AST/OSLog.cpp +++ contrib/llvm-project/clang/lib/AST/OSLog.cpp @@ -56,8 +56,8 @@ public: } bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, - const char *StartSpecifier, - unsigned SpecifierLen) override { + const char *StartSpecifier, unsigned SpecifierLen, + const TargetInfo &) override { if (!FS.consumesDataArgument() && FS.getConversionSpecifier().getKind() != clang::analyze_format_string::ConversionSpecifier::PrintErrno) diff --git contrib/llvm-project/clang/lib/AST/PrintfFormatString.cpp contrib/llvm-project/clang/lib/AST/PrintfFormatString.cpp index fc658d5ba5c3..e5f356187988 100644 --- contrib/llvm-project/clang/lib/AST/PrintfFormatString.cpp +++ contrib/llvm-project/clang/lib/AST/PrintfFormatString.cpp @@ -428,7 +428,7 @@ bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, continue; // We have a format specifier. Pass it to the callback. if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(), - I - FSR.getStart())) + I - FSR.getStart(), Target)) return true; } assert(I == E && "Format string not exhausted"); @@ -711,8 +711,8 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, CS.setKind(ConversionSpecifier::sArg); // Disable irrelevant flags - HasAlternativeForm = 0; - HasLeadingZeroes = 0; + HasAlternativeForm = false; + HasLeadingZeroes = false; // Set the long length modifier for wide characters if (QT->getPointeeType()->isWideCharType()) @@ -878,9 +878,9 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, CS.setKind(ConversionSpecifier::cArg); LM.setKind(LengthModifier::None); Precision.setHowSpecified(OptionalAmount::NotSpecified); - HasAlternativeForm = 0; - HasLeadingZeroes = 0; - HasPlusPrefix = 0; + HasAlternativeForm = false; + HasLeadingZeroes = false; + HasPlusPrefix = false; } // Test for Floating type first as LongDouble can pass isUnsignedIntegerType else if (QT->isRealFloatingType()) { @@ -888,12 +888,12 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, } else if (QT->isSignedIntegerType()) { CS.setKind(ConversionSpecifier::dArg); - HasAlternativeForm = 0; + HasAlternativeForm = false; } else if (QT->isUnsignedIntegerType()) { CS.setKind(ConversionSpecifier::uArg); - HasAlternativeForm = 0; - HasPlusPrefix = 0; + HasAlternativeForm = false; + HasPlusPrefix = false; } else { llvm_unreachable("Unexpected type"); } diff --git contrib/llvm-project/clang/lib/AST/RecordLayoutBuilder.cpp contrib/llvm-project/clang/lib/AST/RecordLayoutBuilder.cpp index 3e39ec1c718d..61a30ead165e 100644 --- contrib/llvm-project/clang/lib/AST/RecordLayoutBuilder.cpp +++ contrib/llvm-project/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2021,6 +2021,7 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D, CharUnits UnpackedFieldAlign = !DefaultsToAIXPowerAlignment ? FieldAlign : PreferredAlign; CharUnits UnpackedFieldOffset = FieldOffset; + CharUnits OriginalFieldAlign = UnpackedFieldAlign; if (FieldPacked) { FieldAlign = CharUnits::One(); @@ -2105,6 +2106,22 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D, // Remember max struct/class ABI-specified alignment. UnadjustedAlignment = std::max(UnadjustedAlignment, FieldAlign); UpdateAlignment(FieldAlign, UnpackedFieldAlign, PreferredAlign); + + // For checking the alignment of inner fields against + // the alignment of its parent record. + if (const RecordDecl *RD = D->getParent()) { + // Check if packed attribute or pragma pack is present. + if (RD->hasAttr<PackedAttr>() || !MaxFieldAlignment.isZero()) + if (FieldAlign < OriginalFieldAlign) + if (D->getType()->isRecordType()) { + // If the offset is a multiple of the alignment of + // the type, raise the warning. + // TODO: Takes no account the alignment of the outer struct + if (FieldOffset % OriginalFieldAlign != 0) + Diag(D->getLocation(), diag::warn_unaligned_access) + << Context.getTypeDeclType(RD) << D->getName() << D->getType(); + } + } } void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) { diff --git contrib/llvm-project/clang/lib/AST/Stmt.cpp contrib/llvm-project/clang/lib/AST/Stmt.cpp index 4f76f6ec12ed..be19d3b2cce2 100644 --- contrib/llvm-project/clang/lib/AST/Stmt.cpp +++ contrib/llvm-project/clang/lib/AST/Stmt.cpp @@ -568,21 +568,20 @@ void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C, /// translate this into a numeric value needed to reference the same operand. /// This returns -1 if the operand name is invalid. int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const { - unsigned NumPlusOperands = 0; - // Check if this is an output operand. - for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) { + unsigned NumOutputs = getNumOutputs(); + for (unsigned i = 0; i != NumOutputs; ++i) if (getOutputName(i) == SymbolicName) return i; - } - for (unsigned i = 0, e = getNumInputs(); i != e; ++i) + unsigned NumInputs = getNumInputs(); + for (unsigned i = 0; i != NumInputs; ++i) if (getInputName(i) == SymbolicName) - return getNumOutputs() + NumPlusOperands + i; + return NumOutputs + i; for (unsigned i = 0, e = getNumLabels(); i != e; ++i) if (getLabelName(i) == SymbolicName) - return i + getNumOutputs() + getNumInputs(); + return NumOutputs + NumInputs + getNumPlusOperands() + i; // Not found. return -1; diff --git contrib/llvm-project/clang/lib/AST/StmtOpenMP.cpp contrib/llvm-project/clang/lib/AST/StmtOpenMP.cpp index b336a0637d5e..8a9f73d3dbf0 100644 --- contrib/llvm-project/clang/lib/AST/StmtOpenMP.cpp +++ contrib/llvm-project/clang/lib/AST/StmtOpenMP.cpp @@ -518,7 +518,7 @@ OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C, bool HasCancel) { auto *Dir = createDirective<OMPSectionDirective>(C, llvm::None, AssociatedStmt, - /*NumChildre=*/0, StartLoc, EndLoc); + /*NumChildren=*/0, StartLoc, EndLoc); Dir->setHasCancel(HasCancel); return Dir; } diff --git contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp index b65a38d1e566..adc0720fe000 100644 --- contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp +++ contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp @@ -1030,7 +1030,12 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { Qualifier->print(OS, Policy); if (Node->hasTemplateKeyword()) OS << "template "; - OS << Node->getNameInfo(); + if (Policy.CleanUglifiedParameters && + isa<ParmVarDecl, NonTypeTemplateParmDecl>(Node->getDecl()) && + Node->getDecl()->getIdentifier()) + OS << Node->getDecl()->getIdentifier()->deuglifiedName(); + else + Node->getNameInfo().printName(OS, Policy); if (Node->hasExplicitTemplateArgs()) { const TemplateParameterList *TPL = nullptr; if (!Node->hadMultipleCandidates()) @@ -2069,7 +2074,10 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) { } else { NeedComma = true; } - std::string ParamStr = P->getNameAsString(); + std::string ParamStr = + (Policy.CleanUglifiedParameters && P->getIdentifier()) + ? P->getIdentifier()->deuglifiedName().str() + : P->getNameAsString(); P->getOriginalType().print(OS, Policy, ParamStr); } if (Method->isVariadic()) { diff --git contrib/llvm-project/clang/lib/AST/TemplateName.cpp contrib/llvm-project/clang/lib/AST/TemplateName.cpp index c8bd74f0b5bb..05d7d58b71c4 100644 --- contrib/llvm-project/clang/lib/AST/TemplateName.cpp +++ contrib/llvm-project/clang/lib/AST/TemplateName.cpp @@ -223,8 +223,12 @@ bool TemplateName::containsUnexpandedParameterPack() const { void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual) const { if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>()) - if (Qual == Qualified::Fully && - getDependence() != TemplateNameDependenceScope::DependentInstantiation) + if (Policy.CleanUglifiedParameters && + isa<TemplateTemplateParmDecl>(Template) && Template->getIdentifier()) + OS << Template->getIdentifier()->deuglifiedName(); + else if (Qual == Qualified::Fully && + getDependence() != + TemplateNameDependenceScope::DependentInstantiation) Template->printQualifiedName(OS, Policy); else OS << *Template; diff --git contrib/llvm-project/clang/lib/AST/Type.cpp contrib/llvm-project/clang/lib/AST/Type.cpp index c771fe264b0c..774b3e94159d 100644 --- contrib/llvm-project/clang/lib/AST/Type.cpp +++ contrib/llvm-project/clang/lib/AST/Type.cpp @@ -194,7 +194,7 @@ void ConstantArrayType::Profile(llvm::FoldingSetNodeID &ID, ID.AddInteger(ArraySize.getZExtValue()); ID.AddInteger(SizeMod); ID.AddInteger(TypeQuals); - ID.AddBoolean(SizeExpr != 0); + ID.AddBoolean(SizeExpr != nullptr); if (SizeExpr) SizeExpr->Profile(ID, Context, true); } diff --git contrib/llvm-project/clang/lib/AST/TypeLoc.cpp contrib/llvm-project/clang/lib/AST/TypeLoc.cpp index c3ed08d5a8b3..13aa54c48f66 100644 --- contrib/llvm-project/clang/lib/AST/TypeLoc.cpp +++ contrib/llvm-project/clang/lib/AST/TypeLoc.cpp @@ -622,6 +622,7 @@ void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) { setFoundDecl(nullptr); setRAngleLoc(Loc); setLAngleLoc(Loc); + setRParenLoc(Loc); TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(), getArgInfos(), Loc); diff --git contrib/llvm-project/clang/lib/AST/TypePrinter.cpp contrib/llvm-project/clang/lib/AST/TypePrinter.cpp index 2a33a69f288d..bba323f651aa 100644 --- contrib/llvm-project/clang/lib/AST/TypePrinter.cpp +++ contrib/llvm-project/clang/lib/AST/TypePrinter.cpp @@ -280,7 +280,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T, case Type::Attributed: { // We still want to print the address_space before the type if it is an // address_space attribute. - const auto *AttrTy = cast<AttributedType>(T); + const auto *AttrTy = cast<AttributedType>(UnderlyingType); CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace; } } @@ -1418,7 +1418,8 @@ void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T, } OS << "auto"; } else if (IdentifierInfo *Id = T->getIdentifier()) - OS << Id->getName(); + OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName() + : Id->getName()); else OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex(); diff --git contrib/llvm-project/clang/lib/AST/VTableBuilder.cpp contrib/llvm-project/clang/lib/AST/VTableBuilder.cpp index f938565c3cb4..24586d6b70d4 100644 --- contrib/llvm-project/clang/lib/AST/VTableBuilder.cpp +++ contrib/llvm-project/clang/lib/AST/VTableBuilder.cpp @@ -2328,7 +2328,7 @@ ItaniumVTableContext::computeVTableRelatedInformation(const CXXRecordDecl *RD) { return; ItaniumVTableBuilder Builder(*this, RD, CharUnits::Zero(), - /*MostDerivedClassIsVirtual=*/0, RD); + /*MostDerivedClassIsVirtual=*/false, RD); Entry = CreateVTableLayout(Builder); MethodVTableIndices.insert(Builder.vtable_indices_begin(), diff --git contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h index fa9d42247e24..3e9c4f31b84d 100644 --- contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -524,8 +524,9 @@ variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange, } return {}; } - InnerArgs.set_size(i + 1); - InnerArgsPtr[i] = new (&InnerArgs[i]) ArgT(ArgTraits::get(Value)); + assert(InnerArgs.size() < InnerArgs.capacity()); + InnerArgs.emplace_back(ArgTraits::get(Value)); + InnerArgsPtr[i] = &InnerArgs[i]; } return outvalueToVariantMatcher(Func(InnerArgsPtr)); } @@ -1166,4 +1167,4 @@ std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall( } // namespace ast_matchers } // namespace clang -#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H +#endif // LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H diff --git contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 4f3efdb0a663..47db6b51966a 100644 --- contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -404,7 +404,9 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(isComparisonOperator); REGISTER_MATCHER(isConst); REGISTER_MATCHER(isConstQualified); + REGISTER_MATCHER(isConsteval); REGISTER_MATCHER(isConstexpr); + REGISTER_MATCHER(isConstinit); REGISTER_MATCHER(isCopyAssignmentOperator); REGISTER_MATCHER(isCopyConstructor); REGISTER_MATCHER(isDefaultConstructor); diff --git contrib/llvm-project/clang/lib/Analysis/CFG.cpp contrib/llvm-project/clang/lib/Analysis/CFG.cpp index 9ef3b5b6277a..8246854dc1b5 100644 --- contrib/llvm-project/clang/lib/Analysis/CFG.cpp +++ contrib/llvm-project/clang/lib/Analysis/CFG.cpp @@ -531,9 +531,7 @@ class CFGBuilder { public: explicit CFGBuilder(ASTContext *astContext, const CFG::BuildOptions &buildOpts) - : Context(astContext), cfg(new CFG()), // crew a new CFG - ConstructionContextMap(), BuildOpts(buildOpts) {} - + : Context(astContext), cfg(new CFG()), BuildOpts(buildOpts) {} // buildCFG - Used by external clients to construct the CFG. std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *Statement); @@ -3354,7 +3352,7 @@ CFGBlock *CFGBuilder::VisitGCCAsmStmt(GCCAsmStmt *G, AddStmtChoice asc) { // Save "Succ" in BackpatchBlocks. In the backpatch processing, "Succ" is // used to avoid adding "Succ" again. BackpatchBlocks.push_back(JumpSource(Succ, ScopePos)); - return Block; + return VisitChildren(G); } CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) { diff --git contrib/llvm-project/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp contrib/llvm-project/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp new file mode 100644 index 000000000000..3ad2ed640cc1 --- /dev/null +++ contrib/llvm-project/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp @@ -0,0 +1,69 @@ +//===- ControlFlowContext.cpp ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines a ControlFlowContext class that is used by dataflow +// analyses that run over Control-Flow Graphs (CFGs). +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Stmt.h" +#include "clang/Analysis/CFG.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Error.h" +#include <utility> + +namespace clang { +namespace dataflow { + +/// Returns a map from statements to basic blocks that contain them. +static llvm::DenseMap<const Stmt *, const CFGBlock *> +buildStmtToBasicBlockMap(const CFG &Cfg) { + llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock; + for (const CFGBlock *Block : Cfg) { + if (Block == nullptr) + continue; + + for (const CFGElement &Element : *Block) { + auto Stmt = Element.getAs<CFGStmt>(); + if (!Stmt.hasValue()) + continue; + + StmtToBlock[Stmt.getValue().getStmt()] = Block; + } + } + return StmtToBlock; +} + +llvm::Expected<ControlFlowContext> +ControlFlowContext::build(const Decl *D, Stmt *S, ASTContext *C) { + CFG::BuildOptions Options; + Options.PruneTriviallyFalseEdges = false; + Options.AddImplicitDtors = true; + Options.AddTemporaryDtors = true; + Options.AddInitializers = true; + Options.AddCXXDefaultInitExprInCtors = true; + + // Ensure that all sub-expressions in basic blocks are evaluated. + Options.setAllAlwaysAdd(); + + auto Cfg = CFG::buildCFG(D, S, C, Options); + if (Cfg == nullptr) + return llvm::createStringError( + std::make_error_code(std::errc::invalid_argument), + "CFG::buildCFG failed"); + + llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock = + buildStmtToBasicBlockMap(*Cfg); + return ControlFlowContext(std::move(Cfg), std::move(StmtToBlock)); +} + +} // namespace dataflow +} // namespace clang diff --git contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp new file mode 100644 index 000000000000..938f7338b640 --- /dev/null +++ contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -0,0 +1,318 @@ +//===-- DataflowEnvironment.cpp ---------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines an Environment class that is used by dataflow analyses +// that run over Control-Flow Graphs (CFGs) to keep track of the state of the +// program at given program points. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/Type.h" +#include "clang/Analysis/FlowSensitive/DataflowLattice.h" +#include "clang/Analysis/FlowSensitive/StorageLocation.h" +#include "clang/Analysis/FlowSensitive/Value.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/Support/ErrorHandling.h" +#include <memory> +#include <utility> + +namespace clang { +namespace dataflow { + +/// Returns a map consisting of key-value entries that are present in both maps. +template <typename K, typename V> +llvm::DenseMap<K, V> intersectDenseMaps(const llvm::DenseMap<K, V> &Map1, + const llvm::DenseMap<K, V> &Map2) { + llvm::DenseMap<K, V> Result; + for (auto &Entry : Map1) { + auto It = Map2.find(Entry.first); + if (It != Map2.end() && Entry.second == It->second) + Result.insert({Entry.first, Entry.second}); + } + return Result; +} + +Environment::Environment(DataflowAnalysisContext &DACtx, + const DeclContext &DeclCtx) + : Environment(DACtx) { + if (const auto *FuncDecl = dyn_cast<FunctionDecl>(&DeclCtx)) { + for (const auto *ParamDecl : FuncDecl->parameters()) { + assert(ParamDecl != nullptr); + auto &ParamLoc = createStorageLocation(*ParamDecl); + setStorageLocation(*ParamDecl, ParamLoc); + if (Value *ParamVal = createValue(ParamDecl->getType())) + setValue(ParamLoc, *ParamVal); + } + } + + if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(&DeclCtx)) { + if (!MethodDecl->isStatic()) { + QualType ThisPointeeType = MethodDecl->getThisObjectType(); + // FIXME: Add support for union types. + if (!ThisPointeeType->isUnionType()) { + auto &ThisPointeeLoc = createStorageLocation(ThisPointeeType); + DACtx.setThisPointeeStorageLocation(ThisPointeeLoc); + if (Value *ThisPointeeVal = createValue(ThisPointeeType)) + setValue(ThisPointeeLoc, *ThisPointeeVal); + } + } + } +} + +bool Environment::operator==(const Environment &Other) const { + assert(DACtx == Other.DACtx); + return DeclToLoc == Other.DeclToLoc && LocToVal == Other.LocToVal; +} + +LatticeJoinEffect Environment::join(const Environment &Other, + Environment::Merger &Merger) { + assert(DACtx == Other.DACtx); + + auto Effect = LatticeJoinEffect::Unchanged; + + const unsigned DeclToLocSizeBefore = DeclToLoc.size(); + DeclToLoc = intersectDenseMaps(DeclToLoc, Other.DeclToLoc); + if (DeclToLocSizeBefore != DeclToLoc.size()) + Effect = LatticeJoinEffect::Changed; + + const unsigned ExprToLocSizeBefore = ExprToLoc.size(); + ExprToLoc = intersectDenseMaps(ExprToLoc, Other.ExprToLoc); + if (ExprToLocSizeBefore != ExprToLoc.size()) + Effect = LatticeJoinEffect::Changed; + + llvm::DenseMap<const StorageLocation *, Value *> MergedLocToVal; + for (auto &Entry : LocToVal) { + const StorageLocation *Loc = Entry.first; + assert(Loc != nullptr); + + Value *Val = Entry.second; + assert(Val != nullptr); + + auto It = Other.LocToVal.find(Loc); + if (It == Other.LocToVal.end()) + continue; + assert(It->second != nullptr); + + if (It->second == Val) { + MergedLocToVal.insert({Loc, Val}); + continue; + } + + // FIXME: Consider destroying `MergedValue` immediately if `Merger::merge` + // returns false to avoid storing unneeded values in `DACtx`. + if (Value *MergedVal = createValue(Loc->getType())) + if (Merger.merge(Loc->getType(), *Val, *It->second, *MergedVal, *this)) + MergedLocToVal.insert({Loc, MergedVal}); + } + const unsigned LocToValSizeBefore = LocToVal.size(); + LocToVal = std::move(MergedLocToVal); + if (LocToValSizeBefore != LocToVal.size()) + Effect = LatticeJoinEffect::Changed; + + return Effect; +} + +StorageLocation &Environment::createStorageLocation(QualType Type) { + assert(!Type.isNull()); + if (Type->isStructureOrClassType() || Type->isUnionType()) { + // FIXME: Explore options to avoid eager initialization of fields as some of + // them might not be needed for a particular analysis. + llvm::DenseMap<const ValueDecl *, StorageLocation *> FieldLocs; + for (const FieldDecl *Field : Type->getAsRecordDecl()->fields()) { + FieldLocs.insert({Field, &createStorageLocation(Field->getType())}); + } + return takeOwnership( + std::make_unique<AggregateStorageLocation>(Type, std::move(FieldLocs))); + } + return takeOwnership(std::make_unique<ScalarStorageLocation>(Type)); +} + +StorageLocation &Environment::createStorageLocation(const VarDecl &D) { + // Evaluated declarations are always assigned the same storage locations to + // ensure that the environment stabilizes across loop iterations. Storage + // locations for evaluated declarations are stored in the analysis context. + if (auto *Loc = DACtx->getStorageLocation(D)) + return *Loc; + auto &Loc = createStorageLocation(D.getType()); + DACtx->setStorageLocation(D, Loc); + return Loc; +} + +StorageLocation &Environment::createStorageLocation(const Expr &E) { + // Evaluated expressions are always assigned the same storage locations to + // ensure that the environment stabilizes across loop iterations. Storage + // locations for evaluated expressions are stored in the analysis context. + if (auto *Loc = DACtx->getStorageLocation(E)) + return *Loc; + auto &Loc = createStorageLocation(E.getType()); + DACtx->setStorageLocation(E, Loc); + return Loc; +} + +void Environment::setStorageLocation(const ValueDecl &D, StorageLocation &Loc) { + assert(DeclToLoc.find(&D) == DeclToLoc.end()); + DeclToLoc[&D] = &Loc; +} + +StorageLocation *Environment::getStorageLocation(const ValueDecl &D, + SkipPast SP) const { + auto It = DeclToLoc.find(&D); + return It == DeclToLoc.end() ? nullptr : &skip(*It->second, SP); +} + +void Environment::setStorageLocation(const Expr &E, StorageLocation &Loc) { + assert(ExprToLoc.find(&E) == ExprToLoc.end()); + ExprToLoc[&E] = &Loc; +} + +StorageLocation *Environment::getStorageLocation(const Expr &E, + SkipPast SP) const { + auto It = ExprToLoc.find(&E); + return It == ExprToLoc.end() ? nullptr : &skip(*It->second, SP); +} + +StorageLocation *Environment::getThisPointeeStorageLocation() const { + return DACtx->getThisPointeeStorageLocation(); +} + +void Environment::setValue(const StorageLocation &Loc, Value &Val) { + LocToVal[&Loc] = &Val; + + if (auto *StructVal = dyn_cast<StructValue>(&Val)) { + auto &AggregateLoc = *cast<AggregateStorageLocation>(&Loc); + + const QualType Type = AggregateLoc.getType(); + assert(Type->isStructureOrClassType()); + + for (const FieldDecl *Field : Type->getAsRecordDecl()->fields()) { + assert(Field != nullptr); + setValue(AggregateLoc.getChild(*Field), StructVal->getChild(*Field)); + } + } +} + +Value *Environment::getValue(const StorageLocation &Loc) const { + auto It = LocToVal.find(&Loc); + return It == LocToVal.end() ? nullptr : It->second; +} + +Value *Environment::getValue(const ValueDecl &D, SkipPast SP) const { + auto *Loc = getStorageLocation(D, SP); + if (Loc == nullptr) + return nullptr; + return getValue(*Loc); +} + +Value *Environment::getValue(const Expr &E, SkipPast SP) const { + auto *Loc = getStorageLocation(E, SP); + if (Loc == nullptr) + return nullptr; + return getValue(*Loc); +} + +Value *Environment::createValue(QualType Type) { + llvm::DenseSet<QualType> Visited; + return createValueUnlessSelfReferential(Type, Visited); +} + +Value *Environment::createValueUnlessSelfReferential( + QualType Type, llvm::DenseSet<QualType> &Visited) { + assert(!Type.isNull()); + + if (Type->isIntegerType()) { + return &takeOwnership(std::make_unique<IntegerValue>()); + } + + if (Type->isReferenceType()) { + QualType PointeeType = Type->getAs<ReferenceType>()->getPointeeType(); + auto &PointeeLoc = createStorageLocation(PointeeType); + + if (!Visited.contains(PointeeType.getCanonicalType())) { + Visited.insert(PointeeType.getCanonicalType()); + Value *PointeeVal = + createValueUnlessSelfReferential(PointeeType, Visited); + Visited.erase(PointeeType.getCanonicalType()); + + if (PointeeVal != nullptr) + setValue(PointeeLoc, *PointeeVal); + } + + return &takeOwnership(std::make_unique<ReferenceValue>(PointeeLoc)); + } + + if (Type->isPointerType()) { + QualType PointeeType = Type->getAs<PointerType>()->getPointeeType(); + auto &PointeeLoc = createStorageLocation(PointeeType); + + if (!Visited.contains(PointeeType.getCanonicalType())) { + Visited.insert(PointeeType.getCanonicalType()); + Value *PointeeVal = + createValueUnlessSelfReferential(PointeeType, Visited); + Visited.erase(PointeeType.getCanonicalType()); + + if (PointeeVal != nullptr) + setValue(PointeeLoc, *PointeeVal); + } + + return &takeOwnership(std::make_unique<PointerValue>(PointeeLoc)); + } + + if (Type->isStructureOrClassType()) { + // FIXME: Initialize only fields that are accessed in the context that is + // being analyzed. + llvm::DenseMap<const ValueDecl *, Value *> FieldValues; + for (const FieldDecl *Field : Type->getAsRecordDecl()->fields()) { + assert(Field != nullptr); + + QualType FieldType = Field->getType(); + if (Visited.contains(FieldType.getCanonicalType())) + continue; + + Visited.insert(FieldType.getCanonicalType()); + FieldValues.insert( + {Field, createValueUnlessSelfReferential(FieldType, Visited)}); + Visited.erase(FieldType.getCanonicalType()); + } + + return &takeOwnership( + std::make_unique<StructValue>(std::move(FieldValues))); + } + + return nullptr; +} + +StorageLocation &Environment::skip(StorageLocation &Loc, SkipPast SP) const { + switch (SP) { + case SkipPast::None: + return Loc; + case SkipPast::Reference: + // References cannot be chained so we only need to skip past one level of + // indirection. + if (auto *Val = dyn_cast_or_null<ReferenceValue>(getValue(Loc))) + return Val->getPointeeLoc(); + return Loc; + case SkipPast::ReferenceThenPointer: + StorageLocation &LocPastRef = skip(Loc, SkipPast::Reference); + if (auto *Val = dyn_cast_or_null<PointerValue>(getValue(LocPastRef))) + return Val->getPointeeLoc(); + return LocPastRef; + } + llvm_unreachable("bad SkipPast kind"); +} + +const StorageLocation &Environment::skip(const StorageLocation &Loc, + SkipPast SP) const { + return skip(*const_cast<StorageLocation *>(&Loc), SP); +} + +} // namespace dataflow +} // namespace clang diff --git contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp new file mode 100644 index 000000000000..51a86b727e33 --- /dev/null +++ contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -0,0 +1,462 @@ +//===-- Transfer.cpp --------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines transfer functions that evaluate program statements and +// update an environment accordingly. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/FlowSensitive/Transfer.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/OperationKinds.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" +#include "clang/Basic/OperatorKinds.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Casting.h" +#include <cassert> +#include <memory> +#include <tuple> + +namespace clang { +namespace dataflow { + +static const Expr *skipExprWithCleanups(const Expr *E) { + if (auto *C = dyn_cast_or_null<ExprWithCleanups>(E)) + return C->getSubExpr(); + return E; +} + +class TransferVisitor : public ConstStmtVisitor<TransferVisitor> { +public: + TransferVisitor(Environment &Env) : Env(Env) {} + + void VisitBinaryOperator(const BinaryOperator *S) { + if (S->getOpcode() == BO_Assign) { + // The CFG does not contain `ParenExpr` as top-level statements in basic + // blocks, however sub-expressions can still be of that type. + assert(S->getLHS() != nullptr); + const Expr *LHS = S->getLHS()->IgnoreParens(); + + assert(LHS != nullptr); + auto *LHSLoc = Env.getStorageLocation(*LHS, SkipPast::Reference); + if (LHSLoc == nullptr) + return; + + // The CFG does not contain `ParenExpr` as top-level statements in basic + // blocks, however sub-expressions can still be of that type. + assert(S->getRHS() != nullptr); + const Expr *RHS = S->getRHS()->IgnoreParens(); + + assert(RHS != nullptr); + Value *RHSVal = Env.getValue(*RHS, SkipPast::Reference); + if (RHSVal == nullptr) + return; + + // Assign a value to the storage location of the left-hand side. + Env.setValue(*LHSLoc, *RHSVal); + + // Assign a storage location for the whole expression. + Env.setStorageLocation(*S, *LHSLoc); + } + // FIXME: Add support for BO_EQ, BO_NE. + } + + void VisitDeclRefExpr(const DeclRefExpr *S) { + assert(S->getDecl() != nullptr); + auto *DeclLoc = Env.getStorageLocation(*S->getDecl(), SkipPast::None); + if (DeclLoc == nullptr) + return; + + if (S->getDecl()->getType()->isReferenceType()) { + Env.setStorageLocation(*S, *DeclLoc); + } else { + auto &Loc = Env.createStorageLocation(*S); + auto &Val = Env.takeOwnership(std::make_unique<ReferenceValue>(*DeclLoc)); + Env.setStorageLocation(*S, Loc); + Env.setValue(Loc, Val); + } + } + + void VisitDeclStmt(const DeclStmt *S) { + // Group decls are converted into single decls in the CFG so the cast below + // is safe. + const auto &D = *cast<VarDecl>(S->getSingleDecl()); + auto &Loc = Env.createStorageLocation(D); + Env.setStorageLocation(D, Loc); + + const Expr *InitExpr = D.getInit(); + if (InitExpr == nullptr) { + // No initializer expression - associate `Loc` with a new value. + if (Value *Val = Env.createValue(D.getType())) + Env.setValue(Loc, *Val); + return; + } + + // The CFG does not contain `ParenExpr` as top-level statements in basic + // blocks, however sub-expressions can still be of that type. + InitExpr = skipExprWithCleanups(D.getInit()->IgnoreParens()); + assert(InitExpr != nullptr); + + if (D.getType()->isReferenceType()) { + // Initializing a reference variable - do not create a reference to + // reference. + if (auto *InitExprLoc = + Env.getStorageLocation(*InitExpr, SkipPast::Reference)) { + auto &Val = + Env.takeOwnership(std::make_unique<ReferenceValue>(*InitExprLoc)); + Env.setValue(Loc, Val); + } else { + // FIXME: The initializer expression must always be assigned a value. + // Replace this with an assert when we have sufficient coverage of + // language features. + if (Value *Val = Env.createValue(D.getType())) + Env.setValue(Loc, *Val); + } + return; + } + + if (auto *InitExprVal = Env.getValue(*InitExpr, SkipPast::None)) { + Env.setValue(Loc, *InitExprVal); + } else if (!D.getType()->isStructureOrClassType()) { + // FIXME: The initializer expression must always be assigned a value. + // Replace this with an assert when we have sufficient coverage of + // language features. + if (Value *Val = Env.createValue(D.getType())) + Env.setValue(Loc, *Val); + } else { + llvm_unreachable("structs and classes must always be assigned values"); + } + } + + void VisitImplicitCastExpr(const ImplicitCastExpr *S) { + // The CFG does not contain `ParenExpr` as top-level statements in basic + // blocks, however sub-expressions can still be of that type. + assert(S->getSubExpr() != nullptr); + const Expr *SubExpr = S->getSubExpr()->IgnoreParens(); + assert(SubExpr != nullptr); + + switch (S->getCastKind()) { + case CK_LValueToRValue: { + auto *SubExprVal = Env.getValue(*SubExpr, SkipPast::Reference); + if (SubExprVal == nullptr) + break; + + auto &ExprLoc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, ExprLoc); + Env.setValue(ExprLoc, *SubExprVal); + break; + } + case CK_NoOp: { + // FIXME: Consider making `Environment::getStorageLocation` skip noop + // expressions (this and other similar expressions in the file) instead of + // assigning them storage locations. + auto *SubExprLoc = Env.getStorageLocation(*SubExpr, SkipPast::None); + if (SubExprLoc == nullptr) + break; + + Env.setStorageLocation(*S, *SubExprLoc); + break; + } + default: + // FIXME: Add support for CK_UserDefinedConversion, + // CK_ConstructorConversion, CK_UncheckedDerivedToBase. + break; + } + } + + void VisitUnaryOperator(const UnaryOperator *S) { + // The CFG does not contain `ParenExpr` as top-level statements in basic + // blocks, however sub-expressions can still be of that type. + assert(S->getSubExpr() != nullptr); + const Expr *SubExpr = S->getSubExpr()->IgnoreParens(); + assert(SubExpr != nullptr); + + switch (S->getOpcode()) { + case UO_Deref: { + // Skip past a reference to handle dereference of a dependent pointer. + const auto *SubExprVal = cast_or_null<PointerValue>( + Env.getValue(*SubExpr, SkipPast::Reference)); + if (SubExprVal == nullptr) + break; + + auto &Loc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, Loc); + Env.setValue(Loc, Env.takeOwnership(std::make_unique<ReferenceValue>( + SubExprVal->getPointeeLoc()))); + break; + } + case UO_AddrOf: { + // Do not form a pointer to a reference. If `SubExpr` is assigned a + // `ReferenceValue` then form a value that points to the location of its + // pointee. + StorageLocation *PointeeLoc = + Env.getStorageLocation(*SubExpr, SkipPast::Reference); + if (PointeeLoc == nullptr) + break; + + auto &PointerLoc = Env.createStorageLocation(*S); + auto &PointerVal = + Env.takeOwnership(std::make_unique<PointerValue>(*PointeeLoc)); + Env.setStorageLocation(*S, PointerLoc); + Env.setValue(PointerLoc, PointerVal); + break; + } + default: + // FIXME: Add support for UO_LNot. + break; + } + } + + void VisitCXXThisExpr(const CXXThisExpr *S) { + auto *ThisPointeeLoc = Env.getThisPointeeStorageLocation(); + assert(ThisPointeeLoc != nullptr); + + auto &Loc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, Loc); + Env.setValue(Loc, Env.takeOwnership( + std::make_unique<PointerValue>(*ThisPointeeLoc))); + } + + void VisitMemberExpr(const MemberExpr *S) { + ValueDecl *Member = S->getMemberDecl(); + assert(Member != nullptr); + + // FIXME: Consider assigning pointer values to function member expressions. + if (Member->isFunctionOrFunctionTemplate()) + return; + + // The receiver can be either a value or a pointer to a value. Skip past the + // indirection to handle both cases. + auto *BaseLoc = cast_or_null<AggregateStorageLocation>( + Env.getStorageLocation(*S->getBase(), SkipPast::ReferenceThenPointer)); + if (BaseLoc == nullptr) + return; + + // FIXME: Add support for union types. + if (BaseLoc->getType()->isUnionType()) + return; + + auto &MemberLoc = BaseLoc->getChild(*Member); + if (MemberLoc.getType()->isReferenceType()) { + Env.setStorageLocation(*S, MemberLoc); + } else { + auto &Loc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, Loc); + Env.setValue( + Loc, Env.takeOwnership(std::make_unique<ReferenceValue>(MemberLoc))); + } + } + + void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) { + const Expr *InitExpr = S->getExpr(); + assert(InitExpr != nullptr); + + Value *InitExprVal = Env.getValue(*InitExpr, SkipPast::None); + if (InitExprVal == nullptr) + return; + + const FieldDecl *Field = S->getField(); + assert(Field != nullptr); + + auto &ThisLoc = + *cast<AggregateStorageLocation>(Env.getThisPointeeStorageLocation()); + auto &FieldLoc = ThisLoc.getChild(*Field); + Env.setValue(FieldLoc, *InitExprVal); + } + + void VisitCXXConstructExpr(const CXXConstructExpr *S) { + const CXXConstructorDecl *ConstructorDecl = S->getConstructor(); + assert(ConstructorDecl != nullptr); + + if (ConstructorDecl->isCopyOrMoveConstructor()) { + assert(S->getNumArgs() == 1); + + const Expr *Arg = S->getArg(0); + assert(Arg != nullptr); + + if (S->isElidable()) { + auto *ArgLoc = Env.getStorageLocation(*Arg, SkipPast::Reference); + if (ArgLoc == nullptr) + return; + + Env.setStorageLocation(*S, *ArgLoc); + } else if (auto *ArgVal = Env.getValue(*Arg, SkipPast::Reference)) { + auto &Loc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, Loc); + Env.setValue(Loc, *ArgVal); + } + return; + } + + auto &Loc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, Loc); + if (Value *Val = Env.createValue(S->getType())) + Env.setValue(Loc, *Val); + } + + void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) { + if (S->getOperator() == OO_Equal) { + assert(S->getNumArgs() == 2); + + const Expr *Arg0 = S->getArg(0); + assert(Arg0 != nullptr); + + const Expr *Arg1 = S->getArg(1); + assert(Arg1 != nullptr); + + // Evaluate only copy and move assignment operators. + auto *Arg0Type = Arg0->getType()->getUnqualifiedDesugaredType(); + auto *Arg1Type = Arg1->getType()->getUnqualifiedDesugaredType(); + if (Arg0Type != Arg1Type) + return; + + auto *ObjectLoc = Env.getStorageLocation(*Arg0, SkipPast::Reference); + if (ObjectLoc == nullptr) + return; + + auto *Val = Env.getValue(*Arg1, SkipPast::Reference); + if (Val == nullptr) + return; + + Env.setValue(*ObjectLoc, *Val); + } + } + + void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) { + if (S->getCastKind() == CK_ConstructorConversion) { + // The CFG does not contain `ParenExpr` as top-level statements in basic + // blocks, however sub-expressions can still be of that type. + assert(S->getSubExpr() != nullptr); + const Expr *SubExpr = S->getSubExpr(); + assert(SubExpr != nullptr); + + auto *SubExprLoc = Env.getStorageLocation(*SubExpr, SkipPast::None); + if (SubExprLoc == nullptr) + return; + + Env.setStorageLocation(*S, *SubExprLoc); + } + } + + void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) { + auto &Loc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, Loc); + if (Value *Val = Env.createValue(S->getType())) + Env.setValue(Loc, *Val); + } + + void VisitCallExpr(const CallExpr *S) { + if (S->isCallToStdMove()) { + assert(S->getNumArgs() == 1); + + const Expr *Arg = S->getArg(0); + assert(Arg != nullptr); + + auto *ArgLoc = Env.getStorageLocation(*Arg, SkipPast::None); + if (ArgLoc == nullptr) + return; + + Env.setStorageLocation(*S, *ArgLoc); + } + } + + void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *S) { + const Expr *SubExpr = S->getSubExpr(); + assert(SubExpr != nullptr); + + auto *SubExprLoc = Env.getStorageLocation(*SubExpr, SkipPast::None); + if (SubExprLoc == nullptr) + return; + + Env.setStorageLocation(*S, *SubExprLoc); + } + + void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) { + const Expr *SubExpr = S->getSubExpr(); + assert(SubExpr != nullptr); + + auto *SubExprLoc = Env.getStorageLocation(*SubExpr, SkipPast::None); + if (SubExprLoc == nullptr) + return; + + Env.setStorageLocation(*S, *SubExprLoc); + } + + void VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) { + if (S->getCastKind() == CK_NoOp) { + const Expr *SubExpr = S->getSubExpr(); + assert(SubExpr != nullptr); + + auto *SubExprLoc = Env.getStorageLocation(*SubExpr, SkipPast::None); + if (SubExprLoc == nullptr) + return; + + Env.setStorageLocation(*S, *SubExprLoc); + } + } + + void VisitConditionalOperator(const ConditionalOperator *S) { + // FIXME: Revisit this once flow conditions are added to the framework. For + // `a = b ? c : d` we can add `b => a == c && !b => a == d` to the flow + // condition. + auto &Loc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, Loc); + if (Value *Val = Env.createValue(S->getType())) + Env.setValue(Loc, *Val); + } + + void VisitInitListExpr(const InitListExpr *S) { + QualType Type = S->getType(); + + auto &Loc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, Loc); + + auto *Val = Env.createValue(Type); + if (Val == nullptr) + return; + + Env.setValue(Loc, *Val); + + if (Type->isStructureOrClassType()) { + for (auto IT : llvm::zip(Type->getAsRecordDecl()->fields(), S->inits())) { + const FieldDecl *Field = std::get<0>(IT); + assert(Field != nullptr); + + const Expr *Init = std::get<1>(IT); + assert(Init != nullptr); + + if (Value *InitVal = Env.getValue(*Init, SkipPast::None)) + cast<StructValue>(Val)->setChild(*Field, *InitVal); + } + } + // FIXME: Implement array initialization. + } + + void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) { + auto &Loc = Env.createStorageLocation(*S); + Env.setStorageLocation(*S, Loc); + Env.setValue(Loc, Env.getBoolLiteralValue(S->getValue())); + } + +private: + Environment &Env; +}; + +void transfer(const Stmt &S, Environment &Env) { + assert(!isa<ParenExpr>(&S)); + TransferVisitor(Env).Visit(&S); +} + +} // namespace dataflow +} // namespace clang diff --git contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 413e8d14bf0a..aaf6a834f5b3 100644 --- contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -11,14 +11,19 @@ // //===----------------------------------------------------------------------===// +#include <memory> #include <utility> #include <vector> +#include "clang/AST/DeclCXX.h" #include "clang/Analysis/Analyses/PostOrderCFGView.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/DataflowWorklist.h" +#include "clang/Analysis/FlowSensitive/Transfer.h" #include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h" +#include "clang/Analysis/FlowSensitive/Value.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/raw_ostream.h" @@ -35,15 +40,44 @@ namespace dataflow { /// already been transferred. States in `BlockStates` that are set to /// `llvm::None` represent basic blocks that are not evaluated yet. static TypeErasedDataflowAnalysisState computeBlockInputState( + const ControlFlowContext &CFCtx, std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> &BlockStates, const CFGBlock &Block, const Environment &InitEnv, TypeErasedDataflowAnalysis &Analysis) { - // FIXME: Consider passing `Block` to `Analysis.typeErasedInitialElement()` - // to enable building analyses like computation of dominators that initialize - // the state of each basic block differently. - TypeErasedDataflowAnalysisState State = {Analysis.typeErasedInitialElement(), - InitEnv}; - for (const CFGBlock *Pred : Block.preds()) { + llvm::DenseSet<const CFGBlock *> Preds; + Preds.insert(Block.pred_begin(), Block.pred_end()); + if (Block.getTerminator().isTemporaryDtorsBranch()) { + // This handles a special case where the code that produced the CFG includes + // a conditional operator with a branch that constructs a temporary and + // calls a destructor annotated as noreturn. The CFG models this as follows: + // + // B1 (contains the condition of the conditional operator) - succs: B2, B3 + // B2 (contains code that does not call a noreturn destructor) - succs: B4 + // B3 (contains code that calls a noreturn destructor) - succs: B4 + // B4 (has temporary destructor terminator) - succs: B5, B6 + // B5 (noreturn block that is associated with the noreturn destructor call) + // B6 (contains code that follows the conditional operator statement) + // + // The first successor (B5 above) of a basic block with a temporary + // destructor terminator (B4 above) is the block that evaluates the + // destructor. If that block has a noreturn element then the predecessor + // block that constructed the temporary object (B3 above) is effectively a + // noreturn block and its state should not be used as input for the state + // of the block that has a temporary destructor terminator (B4 above). This + // holds regardless of which branch of the ternary operator calls the + // noreturn destructor. However, it doesn't cases where a nested ternary + // operator includes a branch that contains a noreturn destructor call. + // + // See `NoreturnDestructorTest` for concrete examples. + if (Block.succ_begin()->getReachableBlock()->hasNoReturnElement()) { + auto StmtBlock = CFCtx.getStmtToBlock().find(Block.getTerminatorStmt()); + assert(StmtBlock != CFCtx.getStmtToBlock().end()); + Preds.erase(StmtBlock->getSecond()); + } + } + + llvm::Optional<TypeErasedDataflowAnalysisState> MaybeState; + for (const CFGBlock *Pred : Preds) { // Skip if the `Block` is unreachable or control flow cannot get past it. if (!Pred || Pred->hasNoReturnElement()) continue; @@ -57,13 +91,79 @@ static TypeErasedDataflowAnalysisState computeBlockInputState( const TypeErasedDataflowAnalysisState &PredState = MaybePredState.getValue(); - Analysis.joinTypeErased(State.Lattice, PredState.Lattice); - State.Env.join(PredState.Env); + if (MaybeState.hasValue()) { + Analysis.joinTypeErased(MaybeState->Lattice, PredState.Lattice); + MaybeState->Env.join(PredState.Env, Analysis); + } else { + MaybeState = PredState; + } + } + if (!MaybeState.hasValue()) { + // FIXME: Consider passing `Block` to `Analysis.typeErasedInitialElement()` + // to enable building analyses like computation of dominators that + // initialize the state of each basic block differently. + MaybeState.emplace(Analysis.typeErasedInitialElement(), InitEnv); + } + return *MaybeState; +} + +/// Transfers `State` by evaluating `CfgStmt` in the context of `Analysis`. +/// `HandleTransferredStmt` (if provided) will be applied to `CfgStmt`, after it +/// is evaluated. +static void +transferCFGStmt(const CFGStmt &CfgStmt, TypeErasedDataflowAnalysis &Analysis, + TypeErasedDataflowAnalysisState &State, + std::function<void(const CFGStmt &, + const TypeErasedDataflowAnalysisState &)> + HandleTransferredStmt) { + const Stmt *S = CfgStmt.getStmt(); + assert(S != nullptr); + + if (Analysis.applyBuiltinTransfer()) + transfer(*S, State.Env); + Analysis.transferTypeErased(S, State.Lattice, State.Env); + + if (HandleTransferredStmt != nullptr) + HandleTransferredStmt(CfgStmt, State); +} + +/// Transfers `State` by evaluating `CfgInit`. +static void transferCFGInitializer(const CFGInitializer &CfgInit, + TypeErasedDataflowAnalysisState &State) { + const auto &ThisLoc = *cast<AggregateStorageLocation>( + State.Env.getThisPointeeStorageLocation()); + + const CXXCtorInitializer *Initializer = CfgInit.getInitializer(); + assert(Initializer != nullptr); + + auto *InitStmt = Initializer->getInit(); + assert(InitStmt != nullptr); + + auto *InitStmtLoc = + State.Env.getStorageLocation(*InitStmt, SkipPast::Reference); + if (InitStmtLoc == nullptr) + return; + + auto *InitStmtVal = State.Env.getValue(*InitStmtLoc); + if (InitStmtVal == nullptr) + return; + + const FieldDecl *Member = Initializer->getMember(); + assert(Member != nullptr); + + if (Member->getType()->isReferenceType()) { + auto &MemberLoc = ThisLoc.getChild(*Member); + State.Env.setValue(MemberLoc, + State.Env.takeOwnership( + std::make_unique<ReferenceValue>(*InitStmtLoc))); + } else { + auto &MemberLoc = ThisLoc.getChild(*Member); + State.Env.setValue(MemberLoc, *InitStmtVal); } - return State; } TypeErasedDataflowAnalysisState transferBlock( + const ControlFlowContext &CFCtx, std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> &BlockStates, const CFGBlock &Block, const Environment &InitEnv, TypeErasedDataflowAnalysis &Analysis, @@ -71,39 +171,37 @@ TypeErasedDataflowAnalysisState transferBlock( const TypeErasedDataflowAnalysisState &)> HandleTransferredStmt) { TypeErasedDataflowAnalysisState State = - computeBlockInputState(BlockStates, Block, InitEnv, Analysis); + computeBlockInputState(CFCtx, BlockStates, Block, InitEnv, Analysis); for (const CFGElement &Element : Block) { - // FIXME: Evaluate other kinds of `CFGElement`. - const llvm::Optional<CFGStmt> Stmt = Element.getAs<CFGStmt>(); - if (!Stmt.hasValue()) - continue; - - // FIXME: Evaluate the statement contained in `Stmt`. - - State.Lattice = Analysis.transferTypeErased(Stmt.getValue().getStmt(), - State.Lattice, State.Env); - if (HandleTransferredStmt != nullptr) - HandleTransferredStmt(Stmt.getValue(), State); + switch (Element.getKind()) { + case CFGElement::Statement: + transferCFGStmt(*Element.getAs<CFGStmt>(), Analysis, State, + HandleTransferredStmt); + break; + case CFGElement::Initializer: + if (Analysis.applyBuiltinTransfer()) + transferCFGInitializer(*Element.getAs<CFGInitializer>(), State); + break; + default: + // FIXME: Evaluate other kinds of `CFGElement`. + break; + } } return State; } std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> -runTypeErasedDataflowAnalysis(const CFG &Cfg, +runTypeErasedDataflowAnalysis(const ControlFlowContext &CFCtx, TypeErasedDataflowAnalysis &Analysis, const Environment &InitEnv) { - // FIXME: Consider enforcing that `Cfg` meets the requirements that - // are specified in the header. This could be done by remembering - // what options were used to build `Cfg` and asserting on them here. - - PostOrderCFGView POV(&Cfg); - ForwardDataflowWorklist Worklist(Cfg, &POV); + PostOrderCFGView POV(&CFCtx.getCFG()); + ForwardDataflowWorklist Worklist(CFCtx.getCFG(), &POV); std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> BlockStates; - BlockStates.resize(Cfg.size(), llvm::None); + BlockStates.resize(CFCtx.getCFG().size(), llvm::None); // The entry basic block doesn't contain statements so it can be skipped. - const CFGBlock &Entry = Cfg.getEntry(); + const CFGBlock &Entry = CFCtx.getCFG().getEntry(); BlockStates[Entry.getBlockID()] = {Analysis.typeErasedInitialElement(), InitEnv}; Worklist.enqueueSuccessors(&Entry); @@ -114,8 +212,8 @@ runTypeErasedDataflowAnalysis(const CFG &Cfg, // FIXME: Consider making the maximum number of iterations configurable. // FIXME: Set up statistics (see llvm/ADT/Statistic.h) to count average number // of iterations, number of functions that time out, etc. - unsigned Iterations = 0; - static constexpr unsigned MaxIterations = 1 << 16; + uint32_t Iterations = 0; + static constexpr uint32_t MaxIterations = 1 << 16; while (const CFGBlock *Block = Worklist.dequeue()) { if (++Iterations > MaxIterations) { llvm::errs() << "Maximum number of iterations reached, giving up.\n"; @@ -125,7 +223,7 @@ runTypeErasedDataflowAnalysis(const CFG &Cfg, const llvm::Optional<TypeErasedDataflowAnalysisState> &OldBlockState = BlockStates[Block->getBlockID()]; TypeErasedDataflowAnalysisState NewBlockState = - transferBlock(BlockStates, *Block, InitEnv, Analysis); + transferBlock(CFCtx, BlockStates, *Block, InitEnv, Analysis); if (OldBlockState.hasValue() && Analysis.isEqualTypeErased(OldBlockState.getValue().Lattice, diff --git contrib/llvm-project/clang/lib/Analysis/UninitializedValues.cpp contrib/llvm-project/clang/lib/Analysis/UninitializedValues.cpp index a38ae34f4b81..811146e50b45 100644 --- contrib/llvm-project/clang/lib/Analysis/UninitializedValues.cpp +++ contrib/llvm-project/clang/lib/Analysis/UninitializedValues.cpp @@ -819,12 +819,11 @@ void TransferFunctions::VisitGCCAsmStmt(GCCAsmStmt *as) { while (const auto *UO = dyn_cast<UnaryOperator>(Ex)) Ex = stripCasts(C, UO->getSubExpr()); + // Mark the variable as potentially uninitialized for those cases where + // it's used on an indirect path, where it's not guaranteed to be + // defined. if (const VarDecl *VD = findVar(Ex).getDecl()) - if (vals[VD] != Initialized) - // If the variable isn't initialized by the time we get here, then we - // mark it as potentially uninitialized for those cases where it's used - // on an indirect path, where it's not guaranteed to be defined. - vals[VD] = MayUninitialized; + vals[VD] = MayUninitialized; } } diff --git contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp index fe35f77782c9..64bcb45a4cd8 100644 --- contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp +++ contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp @@ -84,6 +84,25 @@ DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) { llvm::DenseMap<OSEnvPair::StorageType, Optional<RelatedTargetVersionMapping>> VersionMappings; if (const auto *VM = Obj->getObject("VersionMap")) { + // FIXME: Generalize this out beyond iOS-deriving targets. + // Look for ios_<targetos> version mapping for targets that derive from ios. + for (const auto &KV : *VM) { + auto Pair = StringRef(KV.getFirst()).split("_"); + if (Pair.first.compare_insensitive("ios") == 0) { + llvm::Triple TT(llvm::Twine("--") + Pair.second.lower()); + if (TT.getOS() != llvm::Triple::UnknownOS) { + auto Mapping = RelatedTargetVersionMapping::parseJSON( + *KV.getSecond().getAsObject(), *MaximumDeploymentVersion); + if (Mapping) + VersionMappings[OSEnvPair(llvm::Triple::IOS, + llvm::Triple::UnknownEnvironment, + TT.getOS(), + llvm::Triple::UnknownEnvironment) + .Value] = std::move(Mapping); + } + } + } + if (const auto *Mapping = VM->getObject("macOS_iOSMac")) { auto VersionMap = RelatedTargetVersionMapping::parseJSON( *Mapping, *MaximumDeploymentVersion); diff --git contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp index 9b7ad96b949f..ac4b9d2cd5a2 100644 --- contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp +++ contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp @@ -374,6 +374,12 @@ void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map, DiagnosticMapping Mapping = makeUserMapping(Map, L); Mapping.setUpgradedFromWarning(WasUpgradedFromWarning); + // Make sure we propagate the NoWarningAsError flag from an existing + // mapping (which may be the default mapping). + DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag); + Mapping.setNoWarningAsError(Info.hasNoWarningAsError() || + Mapping.hasNoWarningAsError()); + // Common case; setting all the diagnostics of a group in one place. if ((L.isInvalid() || L == DiagStatesByLoc.getCurDiagStateLoc()) && DiagStatesByLoc.getCurDiagState()) { diff --git contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp index a9f2d09924cd..87db131992e4 100644 --- contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp +++ contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp @@ -33,7 +33,7 @@ struct StaticDiagInfoRec; // platforms. See "How To Write Shared Libraries" by Ulrich Drepper. struct StaticDiagInfoDescriptionStringTable { #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ char ENUM##_desc[sizeof(DESC)]; // clang-format off #include "clang/Basic/DiagnosticCommonKinds.inc" @@ -54,7 +54,7 @@ struct StaticDiagInfoDescriptionStringTable { const StaticDiagInfoDescriptionStringTable StaticDiagInfoDescriptions = { #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ DESC, // clang-format off #include "clang/Basic/DiagnosticCommonKinds.inc" @@ -79,7 +79,7 @@ extern const StaticDiagInfoRec StaticDiagInfo[]; // StaticDiagInfoRec would have extra padding on 64-bit platforms. const uint32_t StaticDiagInfoDescriptionOffsets[] = { #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ offsetof(StaticDiagInfoDescriptionStringTable, ENUM##_desc), // clang-format off #include "clang/Basic/DiagnosticCommonKinds.inc" @@ -115,6 +115,7 @@ struct StaticDiagInfoRec { uint8_t Category : 6; uint8_t WarnNoWerror : 1; uint8_t WarnShowInSystemHeader : 1; + uint8_t WarnShowInSystemMacro : 1; uint16_t OptionGroupIndex : 15; uint16_t Deferrable : 1; @@ -170,7 +171,7 @@ VALIDATE_DIAG_SIZE(REFACTORING) const StaticDiagInfoRec StaticDiagInfo[] = { // clang-format off #define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \ - SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ { \ diag::ENUM, \ DEFAULT_SEVERITY, \ @@ -179,6 +180,7 @@ const StaticDiagInfoRec StaticDiagInfo[] = { CATEGORY, \ NOWERROR, \ SHOWINSYSHEADER, \ + SHOWINSYSMACRO, \ GROUP, \ DEFERRABLE, \ STR_SIZE(DESC, uint16_t)}, @@ -586,6 +588,13 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, Diag.getSourceManager().getExpansionLoc(Loc))) return diag::Severity::Ignored; + // We also ignore warnings due to system macros + bool ShowInSystemMacro = + !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemMacro; + if (State->SuppressSystemWarnings && !ShowInSystemMacro && Loc.isValid() && + Diag.getSourceManager().isInSystemMacro(Loc)) + return diag::Severity::Ignored; + return Result; } diff --git contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp index d811aeec84a0..b86cb7af69bd 100644 --- contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp +++ contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp @@ -309,6 +309,14 @@ IdentifierInfo::isReserved(const LangOptions &LangOpts) const { return ReservedIdentifierStatus::NotReserved; } +StringRef IdentifierInfo::deuglifiedName() const { + StringRef Name = getName(); + if (Name.size() >= 2 && Name.front() == '_' && + (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z'))) + return Name.ltrim('_'); + return Name; +} + tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const { // We use a perfect hash function here involving the length of the keyword, // the first and third character. For preprocessor ID's there are no diff --git contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp index b7408f39bdab..7e89b3f1b804 100644 --- contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp +++ contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp @@ -12,6 +12,17 @@ namespace clang { +const OpenCLOptions::FeatureDepList OpenCLOptions::DependentFeaturesList = { + {"__opencl_c_read_write_images", "__opencl_c_images"}, + {"__opencl_c_3d_image_writes", "__opencl_c_images"}, + {"__opencl_c_pipes", "__opencl_c_generic_address_space"}, + {"__opencl_c_device_enqueue", "__opencl_c_generic_address_space"}, + {"__opencl_c_device_enqueue", "__opencl_c_program_scope_global_variables"}}; + +const llvm::StringMap<llvm::StringRef> OpenCLOptions::FeatureExtensionMap = { + {"cl_khr_fp64", "__opencl_c_fp64"}, + {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}}; + bool OpenCLOptions::isKnown(llvm::StringRef Ext) const { return OptMap.find(Ext) != OptMap.end(); } @@ -108,33 +119,23 @@ void OpenCLOptions::disableAll() { bool OpenCLOptions::diagnoseUnsupportedFeatureDependencies( const TargetInfo &TI, DiagnosticsEngine &Diags) { - // Feature pairs. First feature in a pair requires the second one to be - // supported. - static const llvm::StringMap<llvm::StringRef> DependentFeaturesMap = { - {"__opencl_c_read_write_images", "__opencl_c_images"}, - {"__opencl_c_3d_image_writes", "__opencl_c_images"}, - {"__opencl_c_pipes", "__opencl_c_generic_address_space"}}; - auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); bool IsValid = true; - for (auto &FeaturePair : DependentFeaturesMap) - if (TI.hasFeatureEnabled(OpenCLFeaturesMap, FeaturePair.getKey()) && - !TI.hasFeatureEnabled(OpenCLFeaturesMap, FeaturePair.getValue())) { + for (auto &FeaturePair : DependentFeaturesList) { + auto Feature = FeaturePair.first; + auto Dep = FeaturePair.second; + if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Feature) && + !TI.hasFeatureEnabled(OpenCLFeaturesMap, Dep)) { IsValid = false; - Diags.Report(diag::err_opencl_feature_requires) - << FeaturePair.getKey() << FeaturePair.getValue(); + Diags.Report(diag::err_opencl_feature_requires) << Feature << Dep; } + } return IsValid; } bool OpenCLOptions::diagnoseFeatureExtensionDifferences( const TargetInfo &TI, DiagnosticsEngine &Diags) { - // Extensions and equivalent feature pairs. - static const llvm::StringMap<llvm::StringRef> FeatureExtensionMap = { - {"cl_khr_fp64", "__opencl_c_fp64"}, - {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}}; - auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); bool IsValid = true; diff --git contrib/llvm-project/clang/lib/Basic/TargetID.cpp contrib/llvm-project/clang/lib/Basic/TargetID.cpp index 59d416f0e015..3b8f4c13b9bf 100644 --- contrib/llvm-project/clang/lib/Basic/TargetID.cpp +++ contrib/llvm-project/clang/lib/Basic/TargetID.cpp @@ -15,7 +15,7 @@ namespace clang { -static const llvm::SmallVector<llvm::StringRef, 4> +static llvm::SmallVector<llvm::StringRef, 4> getAllPossibleAMDGPUTargetIDFeatures(const llvm::Triple &T, llvm::StringRef Proc) { // Entries in returned vector should be in alphabetical order. @@ -33,7 +33,7 @@ getAllPossibleAMDGPUTargetIDFeatures(const llvm::Triple &T, return Ret; } -const llvm::SmallVector<llvm::StringRef, 4> +llvm::SmallVector<llvm::StringRef, 4> getAllPossibleTargetIDFeatures(const llvm::Triple &T, llvm::StringRef Processor) { llvm::SmallVector<llvm::StringRef, 4> Ret; diff --git contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp index 646bbe8b7387..e3a2f30febe7 100644 --- contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp +++ contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp @@ -25,7 +25,7 @@ using namespace clang; static const LangASMap DefaultAddrSpaceMap = {0}; // TargetInfo Constructor. -TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { +TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or // SPARC. These should be overridden by concrete targets as needed. BigEndian = !T.isLittleEndian(); @@ -150,6 +150,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { PlatformMinVersion = VersionTuple(); MaxOpenCLWorkGroupSize = 1024; + ProgramAddrSpace = 0; } // Out of line virtual dtor for TargetInfo. @@ -421,6 +422,8 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { OpenCLFeaturesMap, "__opencl_c_generic_address_space"); Opts.OpenCLPipes = hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes"); + Opts.Blocks = + hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_device_enqueue"); } } diff --git contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp index 4089a393b762..8e23cc4c421a 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp +++ contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp @@ -45,6 +45,7 @@ static StringRef getArchVersionString(llvm::AArch64::ArchKind Kind) { case llvm::AArch64::ArchKind::ARMV9A: case llvm::AArch64::ArchKind::ARMV9_1A: case llvm::AArch64::ArchKind::ARMV9_2A: + case llvm::AArch64::ArchKind::ARMV9_3A: return "9"; default: return "8"; @@ -223,6 +224,12 @@ void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts, getTargetDefinesARMV86A(Opts, Builder); } +void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Also include the Armv8.7 defines + getTargetDefinesARMV87A(Opts, Builder); +} + void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts, MacroBuilder &Builder) const { // Armv9-A maps to Armv8.5-A @@ -241,6 +248,12 @@ void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts, getTargetDefinesARMV87A(Opts, Builder); } +void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Armv9.3-A maps to Armv8.8-A + getTargetDefinesARMV88A(Opts, Builder); +} + void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { // Target identification. @@ -446,6 +459,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, case llvm::AArch64::ArchKind::ARMV8_7A: getTargetDefinesARMV87A(Opts, Builder); break; + case llvm::AArch64::ArchKind::ARMV8_8A: + getTargetDefinesARMV88A(Opts, Builder); + break; case llvm::AArch64::ArchKind::ARMV9A: getTargetDefinesARMV9A(Opts, Builder); break; @@ -455,6 +471,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, case llvm::AArch64::ArchKind::ARMV9_2A: getTargetDefinesARMV92A(Opts, Builder); break; + case llvm::AArch64::ArchKind::ARMV9_3A: + getTargetDefinesARMV93A(Opts, Builder); + break; } // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. @@ -524,6 +543,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasMatmulFP64 = false; HasMatmulFP32 = false; HasLSE = false; + HasHBC = false; + HasMOPS = false; ArchKind = llvm::AArch64::ArchKind::INVALID; @@ -532,36 +553,36 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, FPU |= NeonMode; if (Feature == "+sve") { FPU |= SveMode; - HasFullFP16 = 1; + HasFullFP16 = true; } if (Feature == "+sve2") { FPU |= SveMode; - HasFullFP16 = 1; - HasSVE2 = 1; + HasFullFP16 = true; + HasSVE2 = true; } if (Feature == "+sve2-aes") { FPU |= SveMode; - HasFullFP16 = 1; - HasSVE2 = 1; - HasSVE2AES = 1; + HasFullFP16 = true; + HasSVE2 = true; + HasSVE2AES = true; } if (Feature == "+sve2-sha3") { FPU |= SveMode; - HasFullFP16 = 1; - HasSVE2 = 1; - HasSVE2SHA3 = 1; + HasFullFP16 = true; + HasSVE2 = true; + HasSVE2SHA3 = true; } if (Feature == "+sve2-sm4") { FPU |= SveMode; - HasFullFP16 = 1; - HasSVE2 = 1; - HasSVE2SM4 = 1; + HasFullFP16 = true; + HasSVE2 = true; + HasSVE2SM4 = true; } if (Feature == "+sve2-bitperm") { FPU |= SveMode; - HasFullFP16 = 1; - HasSVE2 = 1; - HasSVE2BitPerm = 1; + HasFullFP16 = true; + HasSVE2 = true; + HasSVE2BitPerm = true; } if (Feature == "+f32mm") { FPU |= SveMode; @@ -603,12 +624,16 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, ArchKind = llvm::AArch64::ArchKind::ARMV8_6A; if (Feature == "+v8.7a") ArchKind = llvm::AArch64::ArchKind::ARMV8_7A; + if (Feature == "+v8.8a") + ArchKind = llvm::AArch64::ArchKind::ARMV8_8A; if (Feature == "+v9a") ArchKind = llvm::AArch64::ArchKind::ARMV9A; if (Feature == "+v9.1a") ArchKind = llvm::AArch64::ArchKind::ARMV9_1A; if (Feature == "+v9.2a") ArchKind = llvm::AArch64::ArchKind::ARMV9_2A; + if (Feature == "+v9.3a") + ArchKind = llvm::AArch64::ArchKind::ARMV9_3A; if (Feature == "+v8r") ArchKind = llvm::AArch64::ArchKind::ARMV8R; if (Feature == "+fullfp16") @@ -635,6 +660,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasRandGen = true; if (Feature == "+flagm") HasFlagM = true; + if (Feature == "+hbc") + HasHBC = true; } setDataLayout(); diff --git contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h index 74745df3be8d..ebddce0c1c73 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h +++ contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h @@ -15,6 +15,7 @@ #include "OSTargets.h" #include "clang/Basic/TargetBuiltins.h" +#include "llvm/Support/AArch64TargetParser.h" #include "llvm/Support/TargetParser.h" namespace clang { @@ -53,6 +54,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool HasMatmulFP32; bool HasLSE; bool HasFlagM; + bool HasHBC; + bool HasMOPS; llvm::AArch64::ArchKind ArchKind; @@ -92,12 +95,16 @@ public: MacroBuilder &Builder) const; void getTargetDefinesARMV87A(const LangOptions &Opts, MacroBuilder &Builder) const; + void getTargetDefinesARMV88A(const LangOptions &Opts, + MacroBuilder &Builder) const; void getTargetDefinesARMV9A(const LangOptions &Opts, MacroBuilder &Builder) const; void getTargetDefinesARMV91A(const LangOptions &Opts, MacroBuilder &Builder) const; void getTargetDefinesARMV92A(const LangOptions &Opts, MacroBuilder &Builder) const; + void getTargetDefinesARMV93A(const LangOptions &Opts, + MacroBuilder &Builder) const; void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; diff --git contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp index c619d6cde41d..478a0233398d 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp +++ contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp @@ -212,12 +212,16 @@ StringRef ARMTargetInfo::getCPUAttr() const { return "8_6A"; case llvm::ARM::ArchKind::ARMV8_7A: return "8_7A"; + case llvm::ARM::ArchKind::ARMV8_8A: + return "8_8A"; case llvm::ARM::ArchKind::ARMV9A: return "9A"; case llvm::ARM::ArchKind::ARMV9_1A: return "9_1A"; case llvm::ARM::ArchKind::ARMV9_2A: return "9_2A"; + case llvm::ARM::ArchKind::ARMV9_3A: + return "9_3A"; case llvm::ARM::ArchKind::ARMV8MBaseline: return "8M_BASE"; case llvm::ARM::ArchKind::ARMV8MMainline: @@ -930,9 +934,11 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, case llvm::ARM::ArchKind::ARMV8_4A: case llvm::ARM::ArchKind::ARMV8_5A: case llvm::ARM::ArchKind::ARMV8_6A: + case llvm::ARM::ArchKind::ARMV8_8A: case llvm::ARM::ArchKind::ARMV9A: case llvm::ARM::ArchKind::ARMV9_1A: case llvm::ARM::ArchKind::ARMV9_2A: + case llvm::ARM::ArchKind::ARMV9_3A: getTargetDefinesARMV83A(Opts, Builder); break; } diff --git contrib/llvm-project/clang/lib/Basic/Targets/ARM.h contrib/llvm-project/clang/lib/Basic/Targets/ARM.h index 40c658f3f40e..f074dac57f9b 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/ARM.h +++ contrib/llvm-project/clang/lib/Basic/Targets/ARM.h @@ -18,6 +18,7 @@ #include "clang/Basic/TargetOptions.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ARMTargetParser.h" #include "llvm/Support/TargetParser.h" namespace clang { diff --git contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp index 50b0fc07b311..6266ed72cd5c 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp +++ contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp @@ -24,281 +24,282 @@ namespace targets { struct LLVM_LIBRARY_VISIBILITY MCUInfo { const char *Name; const char *DefineName; + const int NumFlashBanks; // -1 means the device does not support LPM/ELPM. }; // This list should be kept up-to-date with AVRDevices.td in LLVM. static MCUInfo AVRMcus[] = { - {"at90s1200", "__AVR_AT90S1200__"}, - {"attiny11", "__AVR_ATtiny11__"}, - {"attiny12", "__AVR_ATtiny12__"}, - {"attiny15", "__AVR_ATtiny15__"}, - {"attiny28", "__AVR_ATtiny28__"}, - {"at90s2313", "__AVR_AT90S2313__"}, - {"at90s2323", "__AVR_AT90S2323__"}, - {"at90s2333", "__AVR_AT90S2333__"}, - {"at90s2343", "__AVR_AT90S2343__"}, - {"attiny22", "__AVR_ATtiny22__"}, - {"attiny26", "__AVR_ATtiny26__"}, - {"at86rf401", "__AVR_AT86RF401__"}, - {"at90s4414", "__AVR_AT90S4414__"}, - {"at90s4433", "__AVR_AT90S4433__"}, - {"at90s4434", "__AVR_AT90S4434__"}, - {"at90s8515", "__AVR_AT90S8515__"}, - {"at90c8534", "__AVR_AT90c8534__"}, - {"at90s8535", "__AVR_AT90S8535__"}, - {"ata5272", "__AVR_ATA5272__"}, - {"attiny13", "__AVR_ATtiny13__"}, - {"attiny13a", "__AVR_ATtiny13A__"}, - {"attiny2313", "__AVR_ATtiny2313__"}, - {"attiny2313a", "__AVR_ATtiny2313A__"}, - {"attiny24", "__AVR_ATtiny24__"}, - {"attiny24a", "__AVR_ATtiny24A__"}, - {"attiny4313", "__AVR_ATtiny4313__"}, - {"attiny44", "__AVR_ATtiny44__"}, - {"attiny44a", "__AVR_ATtiny44A__"}, - {"attiny84", "__AVR_ATtiny84__"}, - {"attiny84a", "__AVR_ATtiny84A__"}, - {"attiny25", "__AVR_ATtiny25__"}, - {"attiny45", "__AVR_ATtiny45__"}, - {"attiny85", "__AVR_ATtiny85__"}, - {"attiny261", "__AVR_ATtiny261__"}, - {"attiny261a", "__AVR_ATtiny261A__"}, - {"attiny441", "__AVR_ATtiny441__"}, - {"attiny461", "__AVR_ATtiny461__"}, - {"attiny461a", "__AVR_ATtiny461A__"}, - {"attiny841", "__AVR_ATtiny841__"}, - {"attiny861", "__AVR_ATtiny861__"}, - {"attiny861a", "__AVR_ATtiny861A__"}, - {"attiny87", "__AVR_ATtiny87__"}, - {"attiny43u", "__AVR_ATtiny43U__"}, - {"attiny48", "__AVR_ATtiny48__"}, - {"attiny88", "__AVR_ATtiny88__"}, - {"attiny828", "__AVR_ATtiny828__"}, - {"at43usb355", "__AVR_AT43USB355__"}, - {"at76c711", "__AVR_AT76C711__"}, - {"atmega103", "__AVR_ATmega103__"}, - {"at43usb320", "__AVR_AT43USB320__"}, - {"attiny167", "__AVR_ATtiny167__"}, - {"at90usb82", "__AVR_AT90USB82__"}, - {"at90usb162", "__AVR_AT90USB162__"}, - {"ata5505", "__AVR_ATA5505__"}, - {"atmega8u2", "__AVR_ATmega8U2__"}, - {"atmega16u2", "__AVR_ATmega16U2__"}, - {"atmega32u2", "__AVR_ATmega32U2__"}, - {"attiny1634", "__AVR_ATtiny1634__"}, - {"atmega8", "__AVR_ATmega8__"}, - {"ata6289", "__AVR_ATA6289__"}, - {"atmega8a", "__AVR_ATmega8A__"}, - {"ata6285", "__AVR_ATA6285__"}, - {"ata6286", "__AVR_ATA6286__"}, - {"atmega48", "__AVR_ATmega48__"}, - {"atmega48a", "__AVR_ATmega48A__"}, - {"atmega48pa", "__AVR_ATmega48PA__"}, - {"atmega48pb", "__AVR_ATmega48PB__"}, - {"atmega48p", "__AVR_ATmega48P__"}, - {"atmega88", "__AVR_ATmega88__"}, - {"atmega88a", "__AVR_ATmega88A__"}, - {"atmega88p", "__AVR_ATmega88P__"}, - {"atmega88pa", "__AVR_ATmega88PA__"}, - {"atmega88pb", "__AVR_ATmega88PB__"}, - {"atmega8515", "__AVR_ATmega8515__"}, - {"atmega8535", "__AVR_ATmega8535__"}, - {"atmega8hva", "__AVR_ATmega8HVA__"}, - {"at90pwm1", "__AVR_AT90PWM1__"}, - {"at90pwm2", "__AVR_AT90PWM2__"}, - {"at90pwm2b", "__AVR_AT90PWM2B__"}, - {"at90pwm3", "__AVR_AT90PWM3__"}, - {"at90pwm3b", "__AVR_AT90PWM3B__"}, - {"at90pwm81", "__AVR_AT90PWM81__"}, - {"ata5790", "__AVR_ATA5790__"}, - {"ata5795", "__AVR_ATA5795__"}, - {"atmega16", "__AVR_ATmega16__"}, - {"atmega16a", "__AVR_ATmega16A__"}, - {"atmega161", "__AVR_ATmega161__"}, - {"atmega162", "__AVR_ATmega162__"}, - {"atmega163", "__AVR_ATmega163__"}, - {"atmega164a", "__AVR_ATmega164A__"}, - {"atmega164p", "__AVR_ATmega164P__"}, - {"atmega164pa", "__AVR_ATmega164PA__"}, - {"atmega165", "__AVR_ATmega165__"}, - {"atmega165a", "__AVR_ATmega165A__"}, - {"atmega165p", "__AVR_ATmega165P__"}, - {"atmega165pa", "__AVR_ATmega165PA__"}, - {"atmega168", "__AVR_ATmega168__"}, - {"atmega168a", "__AVR_ATmega168A__"}, - {"atmega168p", "__AVR_ATmega168P__"}, - {"atmega168pa", "__AVR_ATmega168PA__"}, - {"atmega168pb", "__AVR_ATmega168PB__"}, - {"atmega169", "__AVR_ATmega169__"}, - {"atmega169a", "__AVR_ATmega169A__"}, - {"atmega169p", "__AVR_ATmega169P__"}, - {"atmega169pa", "__AVR_ATmega169PA__"}, - {"atmega32", "__AVR_ATmega32__"}, - {"atmega32a", "__AVR_ATmega32A__"}, - {"atmega323", "__AVR_ATmega323__"}, - {"atmega324a", "__AVR_ATmega324A__"}, - {"atmega324p", "__AVR_ATmega324P__"}, - {"atmega324pa", "__AVR_ATmega324PA__"}, - {"atmega324pb", "__AVR_ATmega324PB__"}, - {"atmega325", "__AVR_ATmega325__"}, - {"atmega325a", "__AVR_ATmega325A__"}, - {"atmega325p", "__AVR_ATmega325P__"}, - {"atmega325pa", "__AVR_ATmega325PA__"}, - {"atmega3250", "__AVR_ATmega3250__"}, - {"atmega3250a", "__AVR_ATmega3250A__"}, - {"atmega3250p", "__AVR_ATmega3250P__"}, - {"atmega3250pa", "__AVR_ATmega3250PA__"}, - {"atmega328", "__AVR_ATmega328__"}, - {"atmega328p", "__AVR_ATmega328P__"}, - {"atmega328pb", "__AVR_ATmega328PB__"}, - {"atmega329", "__AVR_ATmega329__"}, - {"atmega329a", "__AVR_ATmega329A__"}, - {"atmega329p", "__AVR_ATmega329P__"}, - {"atmega329pa", "__AVR_ATmega329PA__"}, - {"atmega3290", "__AVR_ATmega3290__"}, - {"atmega3290a", "__AVR_ATmega3290A__"}, - {"atmega3290p", "__AVR_ATmega3290P__"}, - {"atmega3290pa", "__AVR_ATmega3290PA__"}, - {"atmega406", "__AVR_ATmega406__"}, - {"atmega64", "__AVR_ATmega64__"}, - {"atmega64a", "__AVR_ATmega64A__"}, - {"atmega640", "__AVR_ATmega640__"}, - {"atmega644", "__AVR_ATmega644__"}, - {"atmega644a", "__AVR_ATmega644A__"}, - {"atmega644p", "__AVR_ATmega644P__"}, - {"atmega644pa", "__AVR_ATmega644PA__"}, - {"atmega645", "__AVR_ATmega645__"}, - {"atmega645a", "__AVR_ATmega645A__"}, - {"atmega645p", "__AVR_ATmega645P__"}, - {"atmega649", "__AVR_ATmega649__"}, - {"atmega649a", "__AVR_ATmega649A__"}, - {"atmega649p", "__AVR_ATmega649P__"}, - {"atmega6450", "__AVR_ATmega6450__"}, - {"atmega6450a", "__AVR_ATmega6450A__"}, - {"atmega6450p", "__AVR_ATmega6450P__"}, - {"atmega6490", "__AVR_ATmega6490__"}, - {"atmega6490a", "__AVR_ATmega6490A__"}, - {"atmega6490p", "__AVR_ATmega6490P__"}, - {"atmega64rfr2", "__AVR_ATmega64RFR2__"}, - {"atmega644rfr2", "__AVR_ATmega644RFR2__"}, - {"atmega16hva", "__AVR_ATmega16HVA__"}, - {"atmega16hva2", "__AVR_ATmega16HVA2__"}, - {"atmega16hvb", "__AVR_ATmega16HVB__"}, - {"atmega16hvbrevb", "__AVR_ATmega16HVBREVB__"}, - {"atmega32hvb", "__AVR_ATmega32HVB__"}, - {"atmega32hvbrevb", "__AVR_ATmega32HVBREVB__"}, - {"atmega64hve", "__AVR_ATmega64HVE__"}, - {"at90can32", "__AVR_AT90CAN32__"}, - {"at90can64", "__AVR_AT90CAN64__"}, - {"at90pwm161", "__AVR_AT90PWM161__"}, - {"at90pwm216", "__AVR_AT90PWM216__"}, - {"at90pwm316", "__AVR_AT90PWM316__"}, - {"atmega32c1", "__AVR_ATmega32C1__"}, - {"atmega64c1", "__AVR_ATmega64C1__"}, - {"atmega16m1", "__AVR_ATmega16M1__"}, - {"atmega32m1", "__AVR_ATmega32M1__"}, - {"atmega64m1", "__AVR_ATmega64M1__"}, - {"atmega16u4", "__AVR_ATmega16U4__"}, - {"atmega32u4", "__AVR_ATmega32U4__"}, - {"atmega32u6", "__AVR_ATmega32U6__"}, - {"at90usb646", "__AVR_AT90USB646__"}, - {"at90usb647", "__AVR_AT90USB647__"}, - {"at90scr100", "__AVR_AT90SCR100__"}, - {"at94k", "__AVR_AT94K__"}, - {"m3000", "__AVR_AT000__"}, - {"atmega128", "__AVR_ATmega128__"}, - {"atmega128a", "__AVR_ATmega128A__"}, - {"atmega1280", "__AVR_ATmega1280__"}, - {"atmega1281", "__AVR_ATmega1281__"}, - {"atmega1284", "__AVR_ATmega1284__"}, - {"atmega1284p", "__AVR_ATmega1284P__"}, - {"atmega128rfa1", "__AVR_ATmega128RFA1__"}, - {"atmega128rfr2", "__AVR_ATmega128RFR2__"}, - {"atmega1284rfr2", "__AVR_ATmega1284RFR2__"}, - {"at90can128", "__AVR_AT90CAN128__"}, - {"at90usb1286", "__AVR_AT90USB1286__"}, - {"at90usb1287", "__AVR_AT90USB1287__"}, - {"atmega2560", "__AVR_ATmega2560__"}, - {"atmega2561", "__AVR_ATmega2561__"}, - {"atmega256rfr2", "__AVR_ATmega256RFR2__"}, - {"atmega2564rfr2", "__AVR_ATmega2564RFR2__"}, - {"atxmega16a4", "__AVR_ATxmega16A4__"}, - {"atxmega16a4u", "__AVR_ATxmega16A4U__"}, - {"atxmega16c4", "__AVR_ATxmega16C4__"}, - {"atxmega16d4", "__AVR_ATxmega16D4__"}, - {"atxmega32a4", "__AVR_ATxmega32A4__"}, - {"atxmega32a4u", "__AVR_ATxmega32A4U__"}, - {"atxmega32c4", "__AVR_ATxmega32C4__"}, - {"atxmega32d4", "__AVR_ATxmega32D4__"}, - {"atxmega32e5", "__AVR_ATxmega32E5__"}, - {"atxmega16e5", "__AVR_ATxmega16E5__"}, - {"atxmega8e5", "__AVR_ATxmega8E5__"}, - {"atxmega32x1", "__AVR_ATxmega32X1__"}, - {"atxmega64a3", "__AVR_ATxmega64A3__"}, - {"atxmega64a3u", "__AVR_ATxmega64A3U__"}, - {"atxmega64a4u", "__AVR_ATxmega64A4U__"}, - {"atxmega64b1", "__AVR_ATxmega64B1__"}, - {"atxmega64b3", "__AVR_ATxmega64B3__"}, - {"atxmega64c3", "__AVR_ATxmega64C3__"}, - {"atxmega64d3", "__AVR_ATxmega64D3__"}, - {"atxmega64d4", "__AVR_ATxmega64D4__"}, - {"atxmega64a1", "__AVR_ATxmega64A1__"}, - {"atxmega64a1u", "__AVR_ATxmega64A1U__"}, - {"atxmega128a3", "__AVR_ATxmega128A3__"}, - {"atxmega128a3u", "__AVR_ATxmega128A3U__"}, - {"atxmega128b1", "__AVR_ATxmega128B1__"}, - {"atxmega128b3", "__AVR_ATxmega128B3__"}, - {"atxmega128c3", "__AVR_ATxmega128C3__"}, - {"atxmega128d3", "__AVR_ATxmega128D3__"}, - {"atxmega128d4", "__AVR_ATxmega128D4__"}, - {"atxmega192a3", "__AVR_ATxmega192A3__"}, - {"atxmega192a3u", "__AVR_ATxmega192A3U__"}, - {"atxmega192c3", "__AVR_ATxmega192C3__"}, - {"atxmega192d3", "__AVR_ATxmega192D3__"}, - {"atxmega256a3", "__AVR_ATxmega256A3__"}, - {"atxmega256a3u", "__AVR_ATxmega256A3U__"}, - {"atxmega256a3b", "__AVR_ATxmega256A3B__"}, - {"atxmega256a3bu", "__AVR_ATxmega256A3BU__"}, - {"atxmega256c3", "__AVR_ATxmega256C3__"}, - {"atxmega256d3", "__AVR_ATxmega256D3__"}, - {"atxmega384c3", "__AVR_ATxmega384C3__"}, - {"atxmega384d3", "__AVR_ATxmega384D3__"}, - {"atxmega128a1", "__AVR_ATxmega128A1__"}, - {"atxmega128a1u", "__AVR_ATxmega128A1U__"}, - {"atxmega128a4u", "__AVR_ATxmega128A4U__"}, - {"attiny4", "__AVR_ATtiny4__"}, - {"attiny5", "__AVR_ATtiny5__"}, - {"attiny9", "__AVR_ATtiny9__"}, - {"attiny10", "__AVR_ATtiny10__"}, - {"attiny20", "__AVR_ATtiny20__"}, - {"attiny40", "__AVR_ATtiny40__"}, - {"attiny102", "__AVR_ATtiny102__"}, - {"attiny104", "__AVR_ATtiny104__"}, - {"attiny202", "__AVR_ATtiny202__"}, - {"attiny402", "__AVR_ATtiny402__"}, - {"attiny204", "__AVR_ATtiny204__"}, - {"attiny404", "__AVR_ATtiny404__"}, - {"attiny804", "__AVR_ATtiny804__"}, - {"attiny1604", "__AVR_ATtiny1604__"}, - {"attiny406", "__AVR_ATtiny406__"}, - {"attiny806", "__AVR_ATtiny806__"}, - {"attiny1606", "__AVR_ATtiny1606__"}, - {"attiny807", "__AVR_ATtiny807__"}, - {"attiny1607", "__AVR_ATtiny1607__"}, - {"attiny212", "__AVR_ATtiny212__"}, - {"attiny412", "__AVR_ATtiny412__"}, - {"attiny214", "__AVR_ATtiny214__"}, - {"attiny414", "__AVR_ATtiny414__"}, - {"attiny814", "__AVR_ATtiny814__"}, - {"attiny1614", "__AVR_ATtiny1614__"}, - {"attiny416", "__AVR_ATtiny416__"}, - {"attiny816", "__AVR_ATtiny816__"}, - {"attiny1616", "__AVR_ATtiny1616__"}, - {"attiny3216", "__AVR_ATtiny3216__"}, - {"attiny417", "__AVR_ATtiny417__"}, - {"attiny817", "__AVR_ATtiny817__"}, - {"attiny1617", "__AVR_ATtiny1617__"}, - {"attiny3217", "__AVR_ATtiny3217__"}, + {"at90s1200", "__AVR_AT90S1200__", 0}, + {"attiny11", "__AVR_ATtiny11__", 0}, + {"attiny12", "__AVR_ATtiny12__", 0}, + {"attiny15", "__AVR_ATtiny15__", 0}, + {"attiny28", "__AVR_ATtiny28__", 0}, + {"at90s2313", "__AVR_AT90S2313__", 1}, + {"at90s2323", "__AVR_AT90S2323__", 1}, + {"at90s2333", "__AVR_AT90S2333__", 1}, + {"at90s2343", "__AVR_AT90S2343__", 1}, + {"attiny22", "__AVR_ATtiny22__", 1}, + {"attiny26", "__AVR_ATtiny26__", 1}, + {"at86rf401", "__AVR_AT86RF401__", 1}, + {"at90s4414", "__AVR_AT90S4414__", 1}, + {"at90s4433", "__AVR_AT90S4433__", 1}, + {"at90s4434", "__AVR_AT90S4434__", 1}, + {"at90s8515", "__AVR_AT90S8515__", 1}, + {"at90c8534", "__AVR_AT90c8534__", 1}, + {"at90s8535", "__AVR_AT90S8535__", 1}, + {"ata5272", "__AVR_ATA5272__", 1}, + {"attiny13", "__AVR_ATtiny13__", 1}, + {"attiny13a", "__AVR_ATtiny13A__", 1}, + {"attiny2313", "__AVR_ATtiny2313__", 1}, + {"attiny2313a", "__AVR_ATtiny2313A__", 1}, + {"attiny24", "__AVR_ATtiny24__", 1}, + {"attiny24a", "__AVR_ATtiny24A__", 1}, + {"attiny4313", "__AVR_ATtiny4313__", 1}, + {"attiny44", "__AVR_ATtiny44__", 1}, + {"attiny44a", "__AVR_ATtiny44A__", 1}, + {"attiny84", "__AVR_ATtiny84__", 1}, + {"attiny84a", "__AVR_ATtiny84A__", 1}, + {"attiny25", "__AVR_ATtiny25__", 1}, + {"attiny45", "__AVR_ATtiny45__", 1}, + {"attiny85", "__AVR_ATtiny85__", 1}, + {"attiny261", "__AVR_ATtiny261__", 1}, + {"attiny261a", "__AVR_ATtiny261A__", 1}, + {"attiny441", "__AVR_ATtiny441__", 1}, + {"attiny461", "__AVR_ATtiny461__", 1}, + {"attiny461a", "__AVR_ATtiny461A__", 1}, + {"attiny841", "__AVR_ATtiny841__", 1}, + {"attiny861", "__AVR_ATtiny861__", 1}, + {"attiny861a", "__AVR_ATtiny861A__", 1}, + {"attiny87", "__AVR_ATtiny87__", 1}, + {"attiny43u", "__AVR_ATtiny43U__", 1}, + {"attiny48", "__AVR_ATtiny48__", 1}, + {"attiny88", "__AVR_ATtiny88__", 1}, + {"attiny828", "__AVR_ATtiny828__", 1}, + {"at43usb355", "__AVR_AT43USB355__", 1}, + {"at76c711", "__AVR_AT76C711__", 1}, + {"atmega103", "__AVR_ATmega103__", 1}, + {"at43usb320", "__AVR_AT43USB320__", 1}, + {"attiny167", "__AVR_ATtiny167__", 1}, + {"at90usb82", "__AVR_AT90USB82__", 1}, + {"at90usb162", "__AVR_AT90USB162__", 1}, + {"ata5505", "__AVR_ATA5505__", 1}, + {"atmega8u2", "__AVR_ATmega8U2__", 1}, + {"atmega16u2", "__AVR_ATmega16U2__", 1}, + {"atmega32u2", "__AVR_ATmega32U2__", 1}, + {"attiny1634", "__AVR_ATtiny1634__", 1}, + {"atmega8", "__AVR_ATmega8__", 1}, + {"ata6289", "__AVR_ATA6289__", 1}, + {"atmega8a", "__AVR_ATmega8A__", 1}, + {"ata6285", "__AVR_ATA6285__", 1}, + {"ata6286", "__AVR_ATA6286__", 1}, + {"atmega48", "__AVR_ATmega48__", 1}, + {"atmega48a", "__AVR_ATmega48A__", 1}, + {"atmega48pa", "__AVR_ATmega48PA__", 1}, + {"atmega48pb", "__AVR_ATmega48PB__", 1}, + {"atmega48p", "__AVR_ATmega48P__", 1}, + {"atmega88", "__AVR_ATmega88__", 1}, + {"atmega88a", "__AVR_ATmega88A__", 1}, + {"atmega88p", "__AVR_ATmega88P__", 1}, + {"atmega88pa", "__AVR_ATmega88PA__", 1}, + {"atmega88pb", "__AVR_ATmega88PB__", 1}, + {"atmega8515", "__AVR_ATmega8515__", 1}, + {"atmega8535", "__AVR_ATmega8535__", 1}, + {"atmega8hva", "__AVR_ATmega8HVA__", 1}, + {"at90pwm1", "__AVR_AT90PWM1__", 1}, + {"at90pwm2", "__AVR_AT90PWM2__", 1}, + {"at90pwm2b", "__AVR_AT90PWM2B__", 1}, + {"at90pwm3", "__AVR_AT90PWM3__", 1}, + {"at90pwm3b", "__AVR_AT90PWM3B__", 1}, + {"at90pwm81", "__AVR_AT90PWM81__", 1}, + {"ata5790", "__AVR_ATA5790__", 1}, + {"ata5795", "__AVR_ATA5795__", 1}, + {"atmega16", "__AVR_ATmega16__", 1}, + {"atmega16a", "__AVR_ATmega16A__", 1}, + {"atmega161", "__AVR_ATmega161__", 1}, + {"atmega162", "__AVR_ATmega162__", 1}, + {"atmega163", "__AVR_ATmega163__", 1}, + {"atmega164a", "__AVR_ATmega164A__", 1}, + {"atmega164p", "__AVR_ATmega164P__", 1}, + {"atmega164pa", "__AVR_ATmega164PA__", 1}, + {"atmega165", "__AVR_ATmega165__", 1}, + {"atmega165a", "__AVR_ATmega165A__", 1}, + {"atmega165p", "__AVR_ATmega165P__", 1}, + {"atmega165pa", "__AVR_ATmega165PA__", 1}, + {"atmega168", "__AVR_ATmega168__", 1}, + {"atmega168a", "__AVR_ATmega168A__", 1}, + {"atmega168p", "__AVR_ATmega168P__", 1}, + {"atmega168pa", "__AVR_ATmega168PA__", 1}, + {"atmega168pb", "__AVR_ATmega168PB__", 1}, + {"atmega169", "__AVR_ATmega169__", 1}, + {"atmega169a", "__AVR_ATmega169A__", 1}, + {"atmega169p", "__AVR_ATmega169P__", 1}, + {"atmega169pa", "__AVR_ATmega169PA__", 1}, + {"atmega32", "__AVR_ATmega32__", 1}, + {"atmega32a", "__AVR_ATmega32A__", 1}, + {"atmega323", "__AVR_ATmega323__", 1}, + {"atmega324a", "__AVR_ATmega324A__", 1}, + {"atmega324p", "__AVR_ATmega324P__", 1}, + {"atmega324pa", "__AVR_ATmega324PA__", 1}, + {"atmega324pb", "__AVR_ATmega324PB__", 1}, + {"atmega325", "__AVR_ATmega325__", 1}, + {"atmega325a", "__AVR_ATmega325A__", 1}, + {"atmega325p", "__AVR_ATmega325P__", 1}, + {"atmega325pa", "__AVR_ATmega325PA__", 1}, + {"atmega3250", "__AVR_ATmega3250__", 1}, + {"atmega3250a", "__AVR_ATmega3250A__", 1}, + {"atmega3250p", "__AVR_ATmega3250P__", 1}, + {"atmega3250pa", "__AVR_ATmega3250PA__", 1}, + {"atmega328", "__AVR_ATmega328__", 1}, + {"atmega328p", "__AVR_ATmega328P__", 1}, + {"atmega328pb", "__AVR_ATmega328PB__", 1}, + {"atmega329", "__AVR_ATmega329__", 1}, + {"atmega329a", "__AVR_ATmega329A__", 1}, + {"atmega329p", "__AVR_ATmega329P__", 1}, + {"atmega329pa", "__AVR_ATmega329PA__", 1}, + {"atmega3290", "__AVR_ATmega3290__", 1}, + {"atmega3290a", "__AVR_ATmega3290A__", 1}, + {"atmega3290p", "__AVR_ATmega3290P__", 1}, + {"atmega3290pa", "__AVR_ATmega3290PA__", 1}, + {"atmega406", "__AVR_ATmega406__", 1}, + {"atmega64", "__AVR_ATmega64__", 1}, + {"atmega64a", "__AVR_ATmega64A__", 1}, + {"atmega640", "__AVR_ATmega640__", 1}, + {"atmega644", "__AVR_ATmega644__", 1}, + {"atmega644a", "__AVR_ATmega644A__", 1}, + {"atmega644p", "__AVR_ATmega644P__", 1}, + {"atmega644pa", "__AVR_ATmega644PA__", 1}, + {"atmega645", "__AVR_ATmega645__", 1}, + {"atmega645a", "__AVR_ATmega645A__", 1}, + {"atmega645p", "__AVR_ATmega645P__", 1}, + {"atmega649", "__AVR_ATmega649__", 1}, + {"atmega649a", "__AVR_ATmega649A__", 1}, + {"atmega649p", "__AVR_ATmega649P__", 1}, + {"atmega6450", "__AVR_ATmega6450__", 1}, + {"atmega6450a", "__AVR_ATmega6450A__", 1}, + {"atmega6450p", "__AVR_ATmega6450P__", 1}, + {"atmega6490", "__AVR_ATmega6490__", 1}, + {"atmega6490a", "__AVR_ATmega6490A__", 1}, + {"atmega6490p", "__AVR_ATmega6490P__", 1}, + {"atmega64rfr2", "__AVR_ATmega64RFR2__", 1}, + {"atmega644rfr2", "__AVR_ATmega644RFR2__", 1}, + {"atmega16hva", "__AVR_ATmega16HVA__", 1}, + {"atmega16hva2", "__AVR_ATmega16HVA2__", 1}, + {"atmega16hvb", "__AVR_ATmega16HVB__", 1}, + {"atmega16hvbrevb", "__AVR_ATmega16HVBREVB__", 1}, + {"atmega32hvb", "__AVR_ATmega32HVB__", 1}, + {"atmega32hvbrevb", "__AVR_ATmega32HVBREVB__", 1}, + {"atmega64hve", "__AVR_ATmega64HVE__", 1}, + {"at90can32", "__AVR_AT90CAN32__", 1}, + {"at90can64", "__AVR_AT90CAN64__", 1}, + {"at90pwm161", "__AVR_AT90PWM161__", 1}, + {"at90pwm216", "__AVR_AT90PWM216__", 1}, + {"at90pwm316", "__AVR_AT90PWM316__", 1}, + {"atmega32c1", "__AVR_ATmega32C1__", 1}, + {"atmega64c1", "__AVR_ATmega64C1__", 1}, + {"atmega16m1", "__AVR_ATmega16M1__", 1}, + {"atmega32m1", "__AVR_ATmega32M1__", 1}, + {"atmega64m1", "__AVR_ATmega64M1__", 1}, + {"atmega16u4", "__AVR_ATmega16U4__", 1}, + {"atmega32u4", "__AVR_ATmega32U4__", 1}, + {"atmega32u6", "__AVR_ATmega32U6__", 1}, + {"at90usb646", "__AVR_AT90USB646__", 1}, + {"at90usb647", "__AVR_AT90USB647__", 1}, + {"at90scr100", "__AVR_AT90SCR100__", 1}, + {"at94k", "__AVR_AT94K__", 1}, + {"m3000", "__AVR_AT000__", 1}, + {"atmega128", "__AVR_ATmega128__", 2}, + {"atmega128a", "__AVR_ATmega128A__", 2}, + {"atmega1280", "__AVR_ATmega1280__", 2}, + {"atmega1281", "__AVR_ATmega1281__", 2}, + {"atmega1284", "__AVR_ATmega1284__", 2}, + {"atmega1284p", "__AVR_ATmega1284P__", 2}, + {"atmega128rfa1", "__AVR_ATmega128RFA1__", 2}, + {"atmega128rfr2", "__AVR_ATmega128RFR2__", 2}, + {"atmega1284rfr2", "__AVR_ATmega1284RFR2__", 2}, + {"at90can128", "__AVR_AT90CAN128__", 2}, + {"at90usb1286", "__AVR_AT90USB1286__", 2}, + {"at90usb1287", "__AVR_AT90USB1287__", 2}, + {"atmega2560", "__AVR_ATmega2560__", 4}, + {"atmega2561", "__AVR_ATmega2561__", 4}, + {"atmega256rfr2", "__AVR_ATmega256RFR2__", 4}, + {"atmega2564rfr2", "__AVR_ATmega2564RFR2__", 4}, + {"atxmega16a4", "__AVR_ATxmega16A4__", 1}, + {"atxmega16a4u", "__AVR_ATxmega16A4U__", 1}, + {"atxmega16c4", "__AVR_ATxmega16C4__", 1}, + {"atxmega16d4", "__AVR_ATxmega16D4__", 1}, + {"atxmega32a4", "__AVR_ATxmega32A4__", 1}, + {"atxmega32a4u", "__AVR_ATxmega32A4U__", 1}, + {"atxmega32c4", "__AVR_ATxmega32C4__", 1}, + {"atxmega32d4", "__AVR_ATxmega32D4__", 1}, + {"atxmega32e5", "__AVR_ATxmega32E5__", 1}, + {"atxmega16e5", "__AVR_ATxmega16E5__", 1}, + {"atxmega8e5", "__AVR_ATxmega8E5__", 1}, + {"atxmega32x1", "__AVR_ATxmega32X1__", 1}, + {"atxmega64a3", "__AVR_ATxmega64A3__", 1}, + {"atxmega64a3u", "__AVR_ATxmega64A3U__", 1}, + {"atxmega64a4u", "__AVR_ATxmega64A4U__", 1}, + {"atxmega64b1", "__AVR_ATxmega64B1__", 1}, + {"atxmega64b3", "__AVR_ATxmega64B3__", 1}, + {"atxmega64c3", "__AVR_ATxmega64C3__", 1}, + {"atxmega64d3", "__AVR_ATxmega64D3__", 1}, + {"atxmega64d4", "__AVR_ATxmega64D4__", 1}, + {"atxmega64a1", "__AVR_ATxmega64A1__", 1}, + {"atxmega64a1u", "__AVR_ATxmega64A1U__", 1}, + {"atxmega128a3", "__AVR_ATxmega128A3__", 2}, + {"atxmega128a3u", "__AVR_ATxmega128A3U__", 2}, + {"atxmega128b1", "__AVR_ATxmega128B1__", 2}, + {"atxmega128b3", "__AVR_ATxmega128B3__", 2}, + {"atxmega128c3", "__AVR_ATxmega128C3__", 2}, + {"atxmega128d3", "__AVR_ATxmega128D3__", 2}, + {"atxmega128d4", "__AVR_ATxmega128D4__", 2}, + {"atxmega192a3", "__AVR_ATxmega192A3__", 3}, + {"atxmega192a3u", "__AVR_ATxmega192A3U__", 3}, + {"atxmega192c3", "__AVR_ATxmega192C3__", 3}, + {"atxmega192d3", "__AVR_ATxmega192D3__", 3}, + {"atxmega256a3", "__AVR_ATxmega256A3__", 4}, + {"atxmega256a3u", "__AVR_ATxmega256A3U__", 4}, + {"atxmega256a3b", "__AVR_ATxmega256A3B__", 4}, + {"atxmega256a3bu", "__AVR_ATxmega256A3BU__", 4}, + {"atxmega256c3", "__AVR_ATxmega256C3__", 4}, + {"atxmega256d3", "__AVR_ATxmega256D3__", 4}, + {"atxmega384c3", "__AVR_ATxmega384C3__", 6}, + {"atxmega384d3", "__AVR_ATxmega384D3__", 6}, + {"atxmega128a1", "__AVR_ATxmega128A1__", 2}, + {"atxmega128a1u", "__AVR_ATxmega128A1U__", 2}, + {"atxmega128a4u", "__AVR_ATxmega128A4U__", 2}, + {"attiny4", "__AVR_ATtiny4__", 0}, + {"attiny5", "__AVR_ATtiny5__", 0}, + {"attiny9", "__AVR_ATtiny9__", 0}, + {"attiny10", "__AVR_ATtiny10__", 0}, + {"attiny20", "__AVR_ATtiny20__", 0}, + {"attiny40", "__AVR_ATtiny40__", 0}, + {"attiny102", "__AVR_ATtiny102__", 0}, + {"attiny104", "__AVR_ATtiny104__", 0}, + {"attiny202", "__AVR_ATtiny202__", 1}, + {"attiny402", "__AVR_ATtiny402__", 1}, + {"attiny204", "__AVR_ATtiny204__", 1}, + {"attiny404", "__AVR_ATtiny404__", 1}, + {"attiny804", "__AVR_ATtiny804__", 1}, + {"attiny1604", "__AVR_ATtiny1604__", 1}, + {"attiny406", "__AVR_ATtiny406__", 1}, + {"attiny806", "__AVR_ATtiny806__", 1}, + {"attiny1606", "__AVR_ATtiny1606__", 1}, + {"attiny807", "__AVR_ATtiny807__", 1}, + {"attiny1607", "__AVR_ATtiny1607__", 1}, + {"attiny212", "__AVR_ATtiny212__", 1}, + {"attiny412", "__AVR_ATtiny412__", 1}, + {"attiny214", "__AVR_ATtiny214__", 1}, + {"attiny414", "__AVR_ATtiny414__", 1}, + {"attiny814", "__AVR_ATtiny814__", 1}, + {"attiny1614", "__AVR_ATtiny1614__", 1}, + {"attiny416", "__AVR_ATtiny416__", 1}, + {"attiny816", "__AVR_ATtiny816__", 1}, + {"attiny1616", "__AVR_ATtiny1616__", 1}, + {"attiny3216", "__AVR_ATtiny3216__", 1}, + {"attiny417", "__AVR_ATtiny417__", 1}, + {"attiny817", "__AVR_ATtiny817__", 1}, + {"attiny1617", "__AVR_ATtiny1617__", 1}, + {"attiny3217", "__AVR_ATtiny3217__", 1}, }; } // namespace targets @@ -330,13 +331,25 @@ void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVR"); Builder.defineMacro("__AVR__"); Builder.defineMacro("__ELF__"); - Builder.defineMacro("__flash", "__attribute__((address_space(1)))"); if (!this->CPU.empty()) { auto It = llvm::find_if( AVRMcus, [&](const MCUInfo &Info) { return Info.Name == this->CPU; }); - if (It != std::end(AVRMcus)) + if (It != std::end(AVRMcus)) { Builder.defineMacro(It->DefineName); + if (It->NumFlashBanks >= 1) + Builder.defineMacro("__flash", "__attribute__((address_space(1)))"); + if (It->NumFlashBanks >= 2) + Builder.defineMacro("__flash1", "__attribute__((address_space(2)))"); + if (It->NumFlashBanks >= 3) + Builder.defineMacro("__flash2", "__attribute__((address_space(3)))"); + if (It->NumFlashBanks >= 4) + Builder.defineMacro("__flash3", "__attribute__((address_space(4)))"); + if (It->NumFlashBanks >= 5) + Builder.defineMacro("__flash4", "__attribute__((address_space(5)))"); + if (It->NumFlashBanks >= 6) + Builder.defineMacro("__flash5", "__attribute__((address_space(6)))"); + } } } diff --git contrib/llvm-project/clang/lib/Basic/Targets/AVR.h contrib/llvm-project/clang/lib/Basic/Targets/AVR.h index 89a80ca6a39a..a281e2c2cd74 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/AVR.h +++ contrib/llvm-project/clang/lib/Basic/Targets/AVR.h @@ -55,6 +55,7 @@ public: Int16Type = SignedInt; Char32Type = UnsignedLong; SigAtomicType = SignedChar; + ProgramAddrSpace = 1; resetDataLayout("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"); } diff --git contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp index c0cd8fa90ed6..ada5b97ed66d 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp +++ contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp @@ -29,7 +29,7 @@ M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - std::string Layout = ""; + std::string Layout; // M68k is Big Endian Layout += "E"; diff --git contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp index 7f7b44b658eb..1eb0317af60b 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp +++ contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp @@ -561,9 +561,9 @@ bool PPCTargetInfo::initFeatureMap( if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) return false; - if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) && + if (!(ArchDefs & ArchDefinePwr7) && (ArchDefs & ArchDefinePpcgr) && llvm::is_contained(FeaturesVec, "+float128")) { - // We have __float128 on PPC but not power 9 and above. + // We have __float128 on PPC but not pre-VSX targets. Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU; return false; } @@ -734,23 +734,28 @@ ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const { const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { // While some of these aliases do map to different registers // they still share the same register name. - {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"}, - {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"}, - {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"}, - {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"}, - {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"}, - {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"}, - {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"}, - {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"}, - {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"}, - {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"}, - {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"}, - {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"}, - {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"}, - {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"}, - {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"}, - {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"}, - {{"cc"}, "cr0"}, + {{"0"}, "r0"}, {{"1", "sp"}, "r1"}, {{"2"}, "r2"}, + {{"3"}, "r3"}, {{"4"}, "r4"}, {{"5"}, "r5"}, + {{"6"}, "r6"}, {{"7"}, "r7"}, {{"8"}, "r8"}, + {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"}, + {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, + {{"15"}, "r15"}, {{"16"}, "r16"}, {{"17"}, "r17"}, + {{"18"}, "r18"}, {{"19"}, "r19"}, {{"20"}, "r20"}, + {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"}, + {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, + {{"27"}, "r27"}, {{"28"}, "r28"}, {{"29"}, "r29"}, + {{"30"}, "r30"}, {{"31"}, "r31"}, {{"fr0"}, "f0"}, + {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"}, + {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, + {{"fr7"}, "f7"}, {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, + {{"fr10"}, "f10"}, {{"fr11"}, "f11"}, {{"fr12"}, "f12"}, + {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"}, + {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, + {{"fr19"}, "f19"}, {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, + {{"fr22"}, "f22"}, {{"fr23"}, "f23"}, {{"fr24"}, "f24"}, + {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"}, + {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, + {{"fr31"}, "f31"}, {{"cc"}, "cr0"}, }; ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const { diff --git contrib/llvm-project/clang/lib/Basic/Targets/PPC.h contrib/llvm-project/clang/lib/Basic/Targets/PPC.h index 60701072ac4b..ac52eb219f54 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/PPC.h +++ contrib/llvm-project/clang/lib/Basic/Targets/PPC.h @@ -414,7 +414,7 @@ public: LongWidth = LongAlign = PointerWidth = PointerAlign = 64; IntMaxType = SignedLong; Int64Type = SignedLong; - std::string DataLayout = ""; + std::string DataLayout; if (Triple.isOSAIX()) { // TODO: Set appropriate ABI for AIX platform. diff --git contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp index 770d37a1c1be..0680cad5b07c 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp +++ contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp @@ -125,6 +125,9 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32"); StringRef CodeModel = getTargetOpts().CodeModel; unsigned FLen = ISAInfo->getFLen(); + unsigned MinVLen = ISAInfo->getMinVLen(); + unsigned MaxELen = ISAInfo->getMaxELen(); + unsigned MaxELenFp = ISAInfo->getMaxELenFp(); if (CodeModel == "default") CodeModel = "small"; @@ -176,10 +179,16 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__riscv_fsqrt"); } + if (MinVLen) { + Builder.defineMacro("__riscv_v_min_vlen", Twine(MinVLen)); + Builder.defineMacro("__riscv_v_elen", Twine(MaxELen)); + Builder.defineMacro("__riscv_v_elen_fp", Twine(MaxELenFp)); + } + if (ISAInfo->hasExtension("c")) Builder.defineMacro("__riscv_compressed"); - if (ISAInfo->hasExtension("v")) + if (ISAInfo->hasExtension("zve32x") || ISAInfo->hasExtension("v")) Builder.defineMacro("__riscv_vector"); } @@ -205,10 +214,26 @@ bool RISCVTargetInfo::initFeatureMap( llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const { - if (getTriple().getArch() == llvm::Triple::riscv64) + unsigned XLen = 32; + + if (getTriple().getArch() == llvm::Triple::riscv64) { Features["64bit"] = true; + XLen = 64; + } + + auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec); + if (!ParseResult) { + std::string Buffer; + llvm::raw_string_ostream OutputErrMsg(Buffer); + handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) { + OutputErrMsg << ErrMsg.getMessage(); + }); + Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str(); + return false; + } - return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); + return TargetInfo::initFeatureMap(Features, Diags, CPU, + (*ParseResult)->toFeatureVector()); } /// Return true if has this feature, need to sync with handleTargetFeatures. diff --git contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp index 5eeb77406c34..932102434801 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp +++ contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp @@ -156,8 +156,6 @@ void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__sparcv8__"); break; case CG_V9: - Builder.defineMacro("__sparcv9"); - Builder.defineMacro("__sparcv9__"); Builder.defineMacro("__sparc_v9__"); break; } diff --git contrib/llvm-project/clang/lib/Basic/Targets/X86.h contrib/llvm-project/clang/lib/Basic/Targets/X86.h index c952b8c9a336..d1b66432e38b 100644 --- contrib/llvm-project/clang/lib/Basic/Targets/X86.h +++ contrib/llvm-project/clang/lib/Basic/Targets/X86.h @@ -533,11 +533,12 @@ public: DoubleAlign = LongLongAlign = 64; bool IsWinCOFF = getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); - resetDataLayout(IsWinCOFF ? "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:" - "64-i64:64-f80:32-n8:16:32-a:0:32-S32" - : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:" - "64-i64:64-f80:32-n8:16:32-a:0:32-S32", - IsWinCOFF ? "_" : ""); + bool IsMSVC = getTriple().isWindowsMSVCEnvironment(); + std::string Layout = IsWinCOFF ? "e-m:x" : "e-m:e"; + Layout += "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-"; + Layout += IsMSVC ? "f80:128" : "f80:32"; + Layout += "-n8:16:32-a:0:32-S32"; + resetDataLayout(Layout, IsWinCOFF ? "_" : ""); } }; diff --git contrib/llvm-project/clang/lib/CodeGen/Address.h contrib/llvm-project/clang/lib/CodeGen/Address.h index 37c20291c0e8..3ac0f4f0d7e5 100644 --- contrib/llvm-project/clang/lib/CodeGen/Address.h +++ contrib/llvm-project/clang/lib/CodeGen/Address.h @@ -14,30 +14,77 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H -#include "llvm/IR/Constants.h" #include "clang/AST/CharUnits.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/IR/Constants.h" +#include "llvm/Support/MathExtras.h" namespace clang { namespace CodeGen { -/// An aligned address. -class Address { +// We try to save some space by using 6 bits over two PointerIntPairs to store +// the alignment. However, some arches don't support 3 bits in a PointerIntPair +// so we fallback to storing the alignment separately. +template <typename T, bool = alignof(llvm::Value *) >= 8> class AddressImpl {}; + +template <typename T> class AddressImpl<T, false> { llvm::Value *Pointer; llvm::Type *ElementType; CharUnits Alignment; +public: + AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType, + CharUnits Alignment) + : Pointer(Pointer), ElementType(ElementType), Alignment(Alignment) {} + llvm::Value *getPointer() const { return Pointer; } + llvm::Type *getElementType() const { return ElementType; } + CharUnits getAlignment() const { return Alignment; } +}; + +template <typename T> class AddressImpl<T, true> { + // Int portion stores upper 3 bits of the log of the alignment. + llvm::PointerIntPair<llvm::Value *, 3, unsigned> Pointer; + // Int portion stores lower 3 bits of the log of the alignment. + llvm::PointerIntPair<llvm::Type *, 3, unsigned> ElementType; + +public: + AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType, + CharUnits Alignment) + : Pointer(Pointer), ElementType(ElementType) { + if (Alignment.isZero()) + return; + // Currently the max supported alignment is much less than 1 << 63 and is + // guaranteed to be a power of 2, so we can store the log of the alignment + // into 6 bits. + assert(Alignment.isPowerOfTwo() && "Alignment cannot be zero"); + auto AlignLog = llvm::Log2_64(Alignment.getQuantity()); + assert(AlignLog < (1 << 6) && "cannot fit alignment into 6 bits"); + this->Pointer.setInt(AlignLog >> 3); + this->ElementType.setInt(AlignLog & 7); + } + llvm::Value *getPointer() const { return Pointer.getPointer(); } + llvm::Type *getElementType() const { return ElementType.getPointer(); } + CharUnits getAlignment() const { + unsigned AlignLog = (Pointer.getInt() << 3) | ElementType.getInt(); + return CharUnits::fromQuantity(CharUnits::QuantityType(1) << AlignLog); + } +}; + +/// An aligned address. +class Address { + AddressImpl<void> A; + protected: - Address(std::nullptr_t) : Pointer(nullptr), ElementType(nullptr) {} + Address(std::nullptr_t) : A(nullptr, nullptr, CharUnits::Zero()) {} public: - Address(llvm::Value *pointer, llvm::Type *elementType, CharUnits alignment) - : Pointer(pointer), ElementType(elementType), Alignment(alignment) { - assert(pointer != nullptr && "Pointer cannot be null"); - assert(elementType != nullptr && "Element type cannot be null"); - assert(llvm::cast<llvm::PointerType>(pointer->getType()) - ->isOpaqueOrPointeeTypeMatches(elementType) && + Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment) + : A(Pointer, ElementType, Alignment) { + assert(Pointer != nullptr && "Pointer cannot be null"); + assert(ElementType != nullptr && "Element type cannot be null"); + assert(llvm::cast<llvm::PointerType>(Pointer->getType()) + ->isOpaqueOrPointeeTypeMatches(ElementType) && "Incorrect pointer element type"); - assert(!alignment.isZero() && "Alignment cannot be zero"); } // Deprecated: Use constructor with explicit element type instead. @@ -46,11 +93,11 @@ public: Alignment) {} static Address invalid() { return Address(nullptr); } - bool isValid() const { return Pointer != nullptr; } + bool isValid() const { return A.getPointer() != nullptr; } llvm::Value *getPointer() const { assert(isValid()); - return Pointer; + return A.getPointer(); } /// Return the type of the pointer value. @@ -61,7 +108,7 @@ public: /// Return the type of the values stored in this address. llvm::Type *getElementType() const { assert(isValid()); - return ElementType; + return A.getElementType(); } /// Return the address space that this address resides in. @@ -77,19 +124,19 @@ public: /// Return the alignment of this pointer. CharUnits getAlignment() const { assert(isValid()); - return Alignment; + return A.getAlignment(); } /// Return address with different pointer, but same element type and /// alignment. Address withPointer(llvm::Value *NewPointer) const { - return Address(NewPointer, ElementType, Alignment); + return Address(NewPointer, getElementType(), getAlignment()); } /// Return address with different alignment, but same pointer and element /// type. Address withAlignment(CharUnits NewAlignment) const { - return Address(Pointer, ElementType, NewAlignment); + return Address(getPointer(), getElementType(), NewAlignment); } }; diff --git contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp index bacac0a20d4d..9ae5c870afc8 100644 --- contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp +++ contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp @@ -197,8 +197,7 @@ public: PassManagerBuilderWrapper(const Triple &TargetTriple, const CodeGenOptions &CGOpts, const LangOptions &LangOpts) - : PassManagerBuilder(), TargetTriple(TargetTriple), CGOpts(CGOpts), - LangOpts(LangOpts) {} + : TargetTriple(TargetTriple), CGOpts(CGOpts), LangOpts(LangOpts) {} const Triple &getTargetTriple() const { return TargetTriple; } const CodeGenOptions &getCGOpts() const { return CGOpts; } const LangOptions &getLangOpts() const { return LangOpts; } @@ -359,7 +358,8 @@ static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder, int TrackOrigins = CGOpts.SanitizeMemoryTrackOrigins; bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Memory); PM.add(createMemorySanitizerLegacyPassPass( - MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel})); + MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel, + CGOpts.SanitizeMemoryParamRetval != 0})); // MemorySanitizer inserts complex instrumentation that mostly follows // the logic of the original code, but operates on "shadow" values. @@ -645,6 +645,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, Options.MCOptions.CommandLineArgs = CodeGenOpts.CommandLineArgs; Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf; Options.ObjectFilenameForDebug = CodeGenOpts.ObjectFilenameForDebug; + Options.Hotpatch = CodeGenOpts.HotPatch; return true; } @@ -1164,11 +1165,11 @@ static void addSanitizers(const Triple &TargetTriple, int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins; bool Recover = CodeGenOpts.SanitizeRecover.has(Mask); - MPM.addPass( - ModuleMemorySanitizerPass({TrackOrigins, Recover, CompileKernel})); + MemorySanitizerOptions options(TrackOrigins, Recover, CompileKernel, + CodeGenOpts.SanitizeMemoryParamRetval); + MPM.addPass(ModuleMemorySanitizerPass(options)); FunctionPassManager FPM; - FPM.addPass( - MemorySanitizerPass({TrackOrigins, Recover, CompileKernel})); + FPM.addPass(MemorySanitizerPass(options)); if (Level != OptimizationLevel::O0) { // MemorySanitizer inserts complex instrumentation that mostly // follows the logic of the original code, but operates on @@ -1491,8 +1492,11 @@ void EmitAssemblyHelper::RunOptimizationPipeline( } // Now that we have all of the passes ready, run them. - PrettyStackTraceString CrashInfo("Optimizer"); - MPM.run(*TheModule, MAM); + { + PrettyStackTraceString CrashInfo("Optimizer"); + llvm::TimeTraceScope TimeScope("Optimizer"); + MPM.run(*TheModule, MAM); + } } void EmitAssemblyHelper::RunCodegenPipeline( @@ -1524,8 +1528,11 @@ void EmitAssemblyHelper::RunCodegenPipeline( return; } - PrettyStackTraceString CrashInfo("Code generation"); - CodeGenPasses.run(*TheModule); + { + PrettyStackTraceString CrashInfo("Code generation"); + llvm::TimeTraceScope TimeScope("CodeGenPasses"); + CodeGenPasses.run(*TheModule); + } } /// A clean version of `EmitAssembly` that uses the new pass manager. diff --git contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp index e81c5ba5055c..10569ae2c3f9 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp @@ -307,7 +307,7 @@ static RValue emitAtomicLibcall(CodeGenFunction &CGF, const CGFunctionInfo &fnInfo = CGF.CGM.getTypes().arrangeBuiltinFunctionCall(resultType, args); llvm::FunctionType *fnTy = CGF.CGM.getTypes().GetFunctionType(fnInfo); - llvm::AttrBuilder fnAttrB; + llvm::AttrBuilder fnAttrB(CGF.getLLVMContext()); fnAttrB.addAttribute(llvm::Attribute::NoUnwind); fnAttrB.addAttribute(llvm::Attribute::WillReturn); llvm::AttributeList fnAttrs = llvm::AttributeList::get( @@ -351,12 +351,12 @@ bool AtomicInfo::requiresMemSetZero(llvm::Type *type) const { bool AtomicInfo::emitMemSetZeroIfNecessary() const { assert(LVal.isSimple()); - llvm::Value *addr = LVal.getPointer(CGF); - if (!requiresMemSetZero(addr->getType()->getPointerElementType())) + Address addr = LVal.getAddress(CGF); + if (!requiresMemSetZero(addr.getElementType())) return false; CGF.Builder.CreateMemSet( - addr, llvm::ConstantInt::get(CGF.Int8Ty, 0), + addr.getPointer(), llvm::ConstantInt::get(CGF.Int8Ty, 0), CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits).getQuantity(), LVal.getAlignment().getAsAlign()); return true; @@ -1522,7 +1522,7 @@ RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, !AsValue)) { auto *ValTy = AsValue ? CGF.ConvertTypeForMem(ValueTy) - : getAtomicAddress().getType()->getPointerElementType(); + : getAtomicAddress().getElementType(); if (ValTy->isIntegerTy()) { assert(IntVal->getType() == ValTy && "Different integer types."); return RValue::get(CGF.EmitFromMemory(IntVal, ValueTy)); diff --git contrib/llvm-project/clang/lib/CodeGen/CGBlocks.cpp contrib/llvm-project/clang/lib/CodeGen/CGBlocks.cpp index 7bb6dbb8a8ac..1f1de3df857c 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGBlocks.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGBlocks.cpp @@ -33,10 +33,10 @@ using namespace clang; using namespace CodeGen; CGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name) - : Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false), - HasCXXObject(false), UsesStret(false), HasCapturedVariableLayout(false), - CapturesNonExternalType(false), LocalAddress(Address::invalid()), - StructureType(nullptr), Block(block) { + : Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false), + NoEscape(false), HasCXXObject(false), UsesStret(false), + HasCapturedVariableLayout(false), CapturesNonExternalType(false), + LocalAddress(Address::invalid()), StructureType(nullptr), Block(block) { // Skip asm prefix, if any. 'name' is usually taken directly from // the mangled name of the enclosing function. @@ -66,17 +66,6 @@ static llvm::Constant *buildDisposeHelper(CodeGenModule &CGM, namespace { -/// Represents a type of copy/destroy operation that should be performed for an -/// entity that's captured by a block. -enum class BlockCaptureEntityKind { - CXXRecord, // Copy or destroy - ARCWeak, - ARCStrong, - NonTrivialCStruct, - BlockObject, // Assign or release - None -}; - /// Represents a captured entity that requires extra operations in order for /// this entity to be copied or destroyed correctly. struct BlockCaptureManagedEntity { @@ -110,11 +99,7 @@ enum class CaptureStrKind { } // end anonymous namespace -static void findBlockCapturedManagedEntities( - const CGBlockInfo &BlockInfo, const LangOptions &LangOpts, - SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures); - -static std::string getBlockCaptureStr(const BlockCaptureManagedEntity &E, +static std::string getBlockCaptureStr(const CGBlockInfo::Capture &Cap, CaptureStrKind StrKind, CharUnits BlockAlignment, CodeGenModule &CGM); @@ -124,34 +109,33 @@ static std::string getBlockDescriptorName(const CGBlockInfo &BlockInfo, std::string Name = "__block_descriptor_"; Name += llvm::to_string(BlockInfo.BlockSize.getQuantity()) + "_"; - if (BlockInfo.needsCopyDisposeHelpers()) { + if (BlockInfo.NeedsCopyDispose) { if (CGM.getLangOpts().Exceptions) Name += "e"; if (CGM.getCodeGenOpts().ObjCAutoRefCountExceptions) Name += "a"; Name += llvm::to_string(BlockInfo.BlockAlign.getQuantity()) + "_"; - SmallVector<BlockCaptureManagedEntity, 4> ManagedCaptures; - findBlockCapturedManagedEntities(BlockInfo, CGM.getContext().getLangOpts(), - ManagedCaptures); + for (auto &Cap : BlockInfo.SortedCaptures) { + if (Cap.isConstantOrTrivial()) + continue; - for (const BlockCaptureManagedEntity &E : ManagedCaptures) { - Name += llvm::to_string(E.Capture->getOffset().getQuantity()); + Name += llvm::to_string(Cap.getOffset().getQuantity()); - if (E.CopyKind == E.DisposeKind) { + if (Cap.CopyKind == Cap.DisposeKind) { // If CopyKind and DisposeKind are the same, merge the capture // information. - assert(E.CopyKind != BlockCaptureEntityKind::None && + assert(Cap.CopyKind != BlockCaptureEntityKind::None && "shouldn't see BlockCaptureManagedEntity that is None"); - Name += getBlockCaptureStr(E, CaptureStrKind::Merged, + Name += getBlockCaptureStr(Cap, CaptureStrKind::Merged, BlockInfo.BlockAlign, CGM); } else { // If CopyKind and DisposeKind are not the same, which can happen when // either Kind is None or the captured object is a __strong block, // concatenate the copy and dispose strings. - Name += getBlockCaptureStr(E, CaptureStrKind::CopyHelper, + Name += getBlockCaptureStr(Cap, CaptureStrKind::CopyHelper, BlockInfo.BlockAlign, CGM); - Name += getBlockCaptureStr(E, CaptureStrKind::DisposeHelper, + Name += getBlockCaptureStr(Cap, CaptureStrKind::DisposeHelper, BlockInfo.BlockAlign, CGM); } } @@ -223,7 +207,7 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, // Optional copy/dispose helpers. bool hasInternalHelper = false; - if (blockInfo.needsCopyDisposeHelpers()) { + if (blockInfo.NeedsCopyDispose) { // copy_func_helper_decl llvm::Constant *copyHelper = buildCopyHelper(CGM, blockInfo); elements.add(copyHelper); @@ -340,17 +324,21 @@ namespace { struct BlockLayoutChunk { CharUnits Alignment; CharUnits Size; - Qualifiers::ObjCLifetime Lifetime; const BlockDecl::Capture *Capture; // null for 'this' llvm::Type *Type; QualType FieldType; + BlockCaptureEntityKind CopyKind, DisposeKind; + BlockFieldFlags CopyFlags, DisposeFlags; BlockLayoutChunk(CharUnits align, CharUnits size, - Qualifiers::ObjCLifetime lifetime, - const BlockDecl::Capture *capture, - llvm::Type *type, QualType fieldType) - : Alignment(align), Size(size), Lifetime(lifetime), - Capture(capture), Type(type), FieldType(fieldType) {} + const BlockDecl::Capture *capture, llvm::Type *type, + QualType fieldType, BlockCaptureEntityKind CopyKind, + BlockFieldFlags CopyFlags, + BlockCaptureEntityKind DisposeKind, + BlockFieldFlags DisposeFlags) + : Alignment(align), Size(size), Capture(capture), Type(type), + FieldType(fieldType), CopyKind(CopyKind), DisposeKind(DisposeKind), + CopyFlags(CopyFlags), DisposeFlags(DisposeFlags) {} /// Tell the block info that this chunk has the given field index. void setIndex(CGBlockInfo &info, unsigned index, CharUnits offset) { @@ -358,32 +346,93 @@ namespace { info.CXXThisIndex = index; info.CXXThisOffset = offset; } else { - auto C = CGBlockInfo::Capture::makeIndex(index, offset, FieldType); - info.Captures.insert({Capture->getVariable(), C}); + info.SortedCaptures.push_back(CGBlockInfo::Capture::makeIndex( + index, offset, FieldType, CopyKind, CopyFlags, DisposeKind, + DisposeFlags, Capture)); } } + + bool isTrivial() const { + return CopyKind == BlockCaptureEntityKind::None && + DisposeKind == BlockCaptureEntityKind::None; + } }; - /// Order by 1) all __strong together 2) next, all byfref together 3) next, - /// all __weak together. Preserve descending alignment in all situations. + /// Order by 1) all __strong together 2) next, all block together 3) next, + /// all byref together 4) next, all __weak together. Preserve descending + /// alignment in all situations. bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) { if (left.Alignment != right.Alignment) return left.Alignment > right.Alignment; auto getPrefOrder = [](const BlockLayoutChunk &chunk) { - if (chunk.Capture && chunk.Capture->isByRef()) - return 1; - if (chunk.Lifetime == Qualifiers::OCL_Strong) + switch (chunk.CopyKind) { + case BlockCaptureEntityKind::ARCStrong: return 0; - if (chunk.Lifetime == Qualifiers::OCL_Weak) - return 2; - return 3; + case BlockCaptureEntityKind::BlockObject: + switch (chunk.CopyFlags.getBitMask()) { + case BLOCK_FIELD_IS_OBJECT: + return 0; + case BLOCK_FIELD_IS_BLOCK: + return 1; + case BLOCK_FIELD_IS_BYREF: + return 2; + default: + break; + } + break; + case BlockCaptureEntityKind::ARCWeak: + return 3; + default: + break; + } + return 4; }; return getPrefOrder(left) < getPrefOrder(right); } } // end anonymous namespace +static std::pair<BlockCaptureEntityKind, BlockFieldFlags> +computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, + const LangOptions &LangOpts); + +static std::pair<BlockCaptureEntityKind, BlockFieldFlags> +computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, + const LangOptions &LangOpts); + +static void addBlockLayout(CharUnits align, CharUnits size, + const BlockDecl::Capture *capture, llvm::Type *type, + QualType fieldType, + SmallVectorImpl<BlockLayoutChunk> &Layout, + CGBlockInfo &Info, CodeGenModule &CGM) { + if (!capture) { + // 'this' capture. + Layout.push_back(BlockLayoutChunk( + align, size, capture, type, fieldType, BlockCaptureEntityKind::None, + BlockFieldFlags(), BlockCaptureEntityKind::None, BlockFieldFlags())); + return; + } + + const LangOptions &LangOpts = CGM.getLangOpts(); + BlockCaptureEntityKind CopyKind, DisposeKind; + BlockFieldFlags CopyFlags, DisposeFlags; + + std::tie(CopyKind, CopyFlags) = + computeCopyInfoForBlockCapture(*capture, fieldType, LangOpts); + std::tie(DisposeKind, DisposeFlags) = + computeDestroyInfoForBlockCapture(*capture, fieldType, LangOpts); + Layout.push_back(BlockLayoutChunk(align, size, capture, type, fieldType, + CopyKind, CopyFlags, DisposeKind, + DisposeFlags)); + + if (Info.NoEscape) + return; + + if (!Layout.back().isTrivial()) + Info.NeedsCopyDispose = true; +} + /// Determines if the given type is safe for constant capture in C++. static bool isSafeForCXXConstantCapture(QualType type) { const RecordType *recordType = @@ -541,6 +590,9 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, CGM.getLangOpts().getGC() == LangOptions::NonGC) info.HasCapturedVariableLayout = true; + if (block->doesNotEscape()) + info.NoEscape = true; + // Collect the layout chunks. SmallVector<BlockLayoutChunk, 16> layout; layout.reserve(block->capturesCXXThis() + @@ -560,9 +612,8 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, auto TInfo = CGM.getContext().getTypeInfoInChars(thisType); maxFieldAlign = std::max(maxFieldAlign, TInfo.Align); - layout.push_back(BlockLayoutChunk(TInfo.Align, TInfo.Width, - Qualifiers::OCL_None, - nullptr, llvmType, thisType)); + addBlockLayout(TInfo.Align, TInfo.Width, nullptr, llvmType, thisType, + layout, info, CGM); } // Next, all the block captures. @@ -570,9 +621,6 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, const VarDecl *variable = CI.getVariable(); if (CI.isEscapingByref()) { - // We have to copy/dispose of the __block reference. - info.NeedsCopyDispose = true; - // Just use void* instead of a pointer to the byref type. CharUnits align = CGM.getPointerAlign(); maxFieldAlign = std::max(maxFieldAlign, align); @@ -581,72 +629,28 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, // the capture field type should always match. assert(CGF && getCaptureFieldType(*CGF, CI) == variable->getType() && "capture type differs from the variable type"); - layout.push_back(BlockLayoutChunk(align, CGM.getPointerSize(), - Qualifiers::OCL_None, &CI, - CGM.VoidPtrTy, variable->getType())); + addBlockLayout(align, CGM.getPointerSize(), &CI, CGM.VoidPtrTy, + variable->getType(), layout, info, CGM); continue; } // Otherwise, build a layout chunk with the size and alignment of // the declaration. if (llvm::Constant *constant = tryCaptureAsConstant(CGM, CGF, variable)) { - info.Captures[variable] = CGBlockInfo::Capture::makeConstant(constant); + info.SortedCaptures.push_back( + CGBlockInfo::Capture::makeConstant(constant, &CI)); continue; } QualType VT = getCaptureFieldType(*CGF, CI); - // If we have a lifetime qualifier, honor it for capture purposes. - // That includes *not* copying it if it's __unsafe_unretained. - Qualifiers::ObjCLifetime lifetime = VT.getObjCLifetime(); - if (lifetime) { - switch (lifetime) { - case Qualifiers::OCL_None: llvm_unreachable("impossible"); - case Qualifiers::OCL_ExplicitNone: - case Qualifiers::OCL_Autoreleasing: - break; - - case Qualifiers::OCL_Strong: - case Qualifiers::OCL_Weak: - info.NeedsCopyDispose = true; - } - - // Block pointers require copy/dispose. So do Objective-C pointers. - } else if (VT->isObjCRetainableType()) { - // But honor the inert __unsafe_unretained qualifier, which doesn't - // actually make it into the type system. - if (VT->isObjCInertUnsafeUnretainedType()) { - lifetime = Qualifiers::OCL_ExplicitNone; - } else { - info.NeedsCopyDispose = true; - // used for mrr below. - lifetime = Qualifiers::OCL_Strong; - } - - // So do types that require non-trivial copy construction. - } else if (CI.hasCopyExpr()) { - info.NeedsCopyDispose = true; - info.HasCXXObject = true; - if (!VT->getAsCXXRecordDecl()->isExternallyVisible()) - info.CapturesNonExternalType = true; - - // So do C structs that require non-trivial copy construction or - // destruction. - } else if (VT.isNonTrivialToPrimitiveCopy() == QualType::PCK_Struct || - VT.isDestructedType() == QualType::DK_nontrivial_c_struct) { - info.NeedsCopyDispose = true; - - // And so do types with destructors. - } else if (CGM.getLangOpts().CPlusPlus) { - if (const CXXRecordDecl *record = VT->getAsCXXRecordDecl()) { - if (!record->hasTrivialDestructor()) { + if (CGM.getLangOpts().CPlusPlus) + if (const CXXRecordDecl *record = VT->getAsCXXRecordDecl()) + if (CI.hasCopyExpr() || !record->hasTrivialDestructor()) { info.HasCXXObject = true; - info.NeedsCopyDispose = true; if (!record->isExternallyVisible()) info.CapturesNonExternalType = true; } - } - } CharUnits size = C.getTypeSizeInChars(VT); CharUnits align = C.getDeclAlign(variable); @@ -656,8 +660,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, llvm::Type *llvmType = CGM.getTypes().ConvertTypeForMem(VT); - layout.push_back( - BlockLayoutChunk(align, size, lifetime, &CI, llvmType, VT)); + addBlockLayout(align, size, &CI, llvmType, VT, layout, info, CGM); } // If that was everything, we're done here. @@ -665,6 +668,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, info.StructureType = llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); info.CanBeGlobal = true; + info.buildCaptureMap(); return; } @@ -718,6 +722,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, // ...until we get to the alignment of the maximum field. if (endAlign >= maxFieldAlign) { + ++li; break; } } @@ -770,6 +775,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, endAlign = getLowBit(blockSize); } + info.buildCaptureMap(); info.StructureType = llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); } @@ -826,7 +832,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { // If the block is non-escaping, set field 'isa 'to NSConcreteGlobalBlock // and set the BLOCK_IS_GLOBAL bit of field 'flags'. Copying a non-escaping // block just returns the original block and releasing it is a no-op. - llvm::Constant *blockISA = blockInfo.getBlockDecl()->doesNotEscape() + llvm::Constant *blockISA = blockInfo.NoEscape ? CGM.getNSConcreteGlobalBlock() : CGM.getNSConcreteStackBlock(); isa = llvm::ConstantExpr::getBitCast(blockISA, VoidPtrTy); @@ -838,13 +844,13 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { flags = BLOCK_HAS_SIGNATURE; if (blockInfo.HasCapturedVariableLayout) flags |= BLOCK_HAS_EXTENDED_LAYOUT; - if (blockInfo.needsCopyDisposeHelpers()) + if (blockInfo.NeedsCopyDispose) flags |= BLOCK_HAS_COPY_DISPOSE; if (blockInfo.HasCXXObject) flags |= BLOCK_HAS_CXX_OBJ; if (blockInfo.UsesStret) flags |= BLOCK_USE_STRET; - if (blockInfo.getBlockDecl()->doesNotEscape()) + if (blockInfo.NoEscape) flags |= BLOCK_IS_NOESCAPE | BLOCK_IS_GLOBAL; } @@ -1033,7 +1039,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { } // Push a cleanup for the capture if necessary. - if (!blockInfo.NeedsCopyDispose) + if (!blockInfo.NoEscape && !blockInfo.NeedsCopyDispose) continue; // Ignore __block captures; there's nothing special in the on-stack block @@ -1654,6 +1660,11 @@ computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, // For all other types, the memcpy is fine. return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags()); + // Honor the inert __unsafe_unretained qualifier, which doesn't actually + // make it into the type system. + if (T->isObjCInertUnsafeUnretainedType()) + return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags()); + // Special rules for ARC captures: Qualifiers QS = T.getQualifiers(); @@ -1669,34 +1680,6 @@ computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, llvm_unreachable("after exhaustive PrimitiveCopyKind switch"); } -static std::pair<BlockCaptureEntityKind, BlockFieldFlags> -computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, - const LangOptions &LangOpts); - -/// Find the set of block captures that need to be explicitly copied or destroy. -static void findBlockCapturedManagedEntities( - const CGBlockInfo &BlockInfo, const LangOptions &LangOpts, - SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures) { - for (const auto &CI : BlockInfo.getBlockDecl()->captures()) { - const VarDecl *Variable = CI.getVariable(); - const CGBlockInfo::Capture &Capture = BlockInfo.getCapture(Variable); - if (Capture.isConstant()) - continue; - - QualType VT = Capture.fieldType(); - auto CopyInfo = computeCopyInfoForBlockCapture(CI, VT, LangOpts); - auto DisposeInfo = computeDestroyInfoForBlockCapture(CI, VT, LangOpts); - if (CopyInfo.first != BlockCaptureEntityKind::None || - DisposeInfo.first != BlockCaptureEntityKind::None) - ManagedCaptures.emplace_back(CopyInfo.first, DisposeInfo.first, - CopyInfo.second, DisposeInfo.second, CI, - Capture); - } - - // Sort the captures by offset. - llvm::sort(ManagedCaptures); -} - namespace { /// Release a __block variable. struct CallBlockRelease final : EHScopeStack::Cleanup { @@ -1732,13 +1715,13 @@ bool CodeGenFunction::cxxDestructorCanThrow(QualType T) { } // Return a string that has the information about a capture. -static std::string getBlockCaptureStr(const BlockCaptureManagedEntity &E, +static std::string getBlockCaptureStr(const CGBlockInfo::Capture &Cap, CaptureStrKind StrKind, CharUnits BlockAlignment, CodeGenModule &CGM) { std::string Str; ASTContext &Ctx = CGM.getContext(); - const BlockDecl::Capture &CI = *E.CI; + const BlockDecl::Capture &CI = *Cap.Cap; QualType CaptureTy = CI.getVariable()->getType(); BlockCaptureEntityKind Kind; @@ -1747,15 +1730,16 @@ static std::string getBlockCaptureStr(const BlockCaptureManagedEntity &E, // CaptureStrKind::Merged should be passed only when the operations and the // flags are the same for copy and dispose. assert((StrKind != CaptureStrKind::Merged || - (E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) && + (Cap.CopyKind == Cap.DisposeKind && + Cap.CopyFlags == Cap.DisposeFlags)) && "different operations and flags"); if (StrKind == CaptureStrKind::DisposeHelper) { - Kind = E.DisposeKind; - Flags = E.DisposeFlags; + Kind = Cap.DisposeKind; + Flags = Cap.DisposeFlags; } else { - Kind = E.CopyKind; - Flags = E.CopyFlags; + Kind = Cap.CopyKind; + Flags = Cap.CopyFlags; } switch (Kind) { @@ -1803,8 +1787,7 @@ static std::string getBlockCaptureStr(const BlockCaptureManagedEntity &E, } case BlockCaptureEntityKind::NonTrivialCStruct: { bool IsVolatile = CaptureTy.isVolatileQualified(); - CharUnits Alignment = - BlockAlignment.alignmentAtOffset(E.Capture->getOffset()); + CharUnits Alignment = BlockAlignment.alignmentAtOffset(Cap.getOffset()); Str += "n"; std::string FuncStr; @@ -1829,7 +1812,7 @@ static std::string getBlockCaptureStr(const BlockCaptureManagedEntity &E, } static std::string getCopyDestroyHelperFuncName( - const SmallVectorImpl<BlockCaptureManagedEntity> &Captures, + const SmallVectorImpl<CGBlockInfo::Capture> &Captures, CharUnits BlockAlignment, CaptureStrKind StrKind, CodeGenModule &CGM) { assert((StrKind == CaptureStrKind::CopyHelper || StrKind == CaptureStrKind::DisposeHelper) && @@ -1843,9 +1826,11 @@ static std::string getCopyDestroyHelperFuncName( Name += "a"; Name += llvm::to_string(BlockAlignment.getQuantity()) + "_"; - for (const BlockCaptureManagedEntity &E : Captures) { - Name += llvm::to_string(E.Capture->getOffset().getQuantity()); - Name += getBlockCaptureStr(E, StrKind, BlockAlignment, CGM); + for (auto &Cap : Captures) { + if (Cap.isConstantOrTrivial()) + continue; + Name += llvm::to_string(Cap.getOffset().getQuantity()); + Name += getBlockCaptureStr(Cap, StrKind, BlockAlignment, CGM); } return Name; @@ -1916,11 +1901,9 @@ static void setBlockHelperAttributesVisibility(bool CapturesNonExternalType, /// the contents of an individual __block variable to the heap. llvm::Constant * CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { - SmallVector<BlockCaptureManagedEntity, 4> CopiedCaptures; - findBlockCapturedManagedEntities(blockInfo, getLangOpts(), CopiedCaptures); - std::string FuncName = - getCopyDestroyHelperFuncName(CopiedCaptures, blockInfo.BlockAlign, - CaptureStrKind::CopyHelper, CGM); + std::string FuncName = getCopyDestroyHelperFuncName( + blockInfo.SortedCaptures, blockInfo.BlockAlign, + CaptureStrKind::CopyHelper, CGM); if (llvm::GlobalValue *Func = CGM.getModule().getNamedValue(FuncName)) return llvm::ConstantExpr::getBitCast(Func, VoidPtrTy); @@ -1967,17 +1950,19 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { dst = Address(Builder.CreateLoad(dst), blockInfo.BlockAlign); dst = Builder.CreateBitCast(dst, structPtrTy, "block.dest"); - for (const auto &CopiedCapture : CopiedCaptures) { - const BlockDecl::Capture &CI = *CopiedCapture.CI; - const CGBlockInfo::Capture &capture = *CopiedCapture.Capture; + for (auto &capture : blockInfo.SortedCaptures) { + if (capture.isConstantOrTrivial()) + continue; + + const BlockDecl::Capture &CI = *capture.Cap; QualType captureType = CI.getVariable()->getType(); - BlockFieldFlags flags = CopiedCapture.CopyFlags; + BlockFieldFlags flags = capture.CopyFlags; unsigned index = capture.getIndex(); Address srcField = Builder.CreateStructGEP(src, index); Address dstField = Builder.CreateStructGEP(dst, index); - switch (CopiedCapture.CopyKind) { + switch (capture.CopyKind) { case BlockCaptureEntityKind::CXXRecord: // If there's an explicit copy expression, we do that. assert(CI.getCopyExpr() && "copy expression for variable is missing"); @@ -2040,7 +2025,7 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { // Ensure that we destroy the copied object if an exception is thrown later // in the helper function. - pushCaptureCleanup(CopiedCapture.CopyKind, dstField, captureType, flags, + pushCaptureCleanup(capture.CopyKind, dstField, captureType, flags, /*ForCopyHelper*/ true, CI.getVariable(), *this); } @@ -2085,8 +2070,10 @@ computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, BlockFieldFlags()); case QualType::DK_none: { // Non-ARC captures are strong, and we need to use _Block_object_dispose. + // But honor the inert __unsafe_unretained qualifier, which doesn't actually + // make it into the type system. if (T->isObjCRetainableType() && !T.getQualifiers().hasObjCLifetime() && - !LangOpts.ObjCAutoRefCount) + !LangOpts.ObjCAutoRefCount && !T->isObjCInertUnsafeUnretainedType()) return std::make_pair(BlockCaptureEntityKind::BlockObject, getBlockFieldFlagsForObjCObjectPointer(CI, T)); // Otherwise, we have nothing to do. @@ -2105,11 +2092,9 @@ computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, /// variable. llvm::Constant * CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { - SmallVector<BlockCaptureManagedEntity, 4> DestroyedCaptures; - findBlockCapturedManagedEntities(blockInfo, getLangOpts(), DestroyedCaptures); - std::string FuncName = - getCopyDestroyHelperFuncName(DestroyedCaptures, blockInfo.BlockAlign, - CaptureStrKind::DisposeHelper, CGM); + std::string FuncName = getCopyDestroyHelperFuncName( + blockInfo.SortedCaptures, blockInfo.BlockAlign, + CaptureStrKind::DisposeHelper, CGM); if (llvm::GlobalValue *Func = CGM.getModule().getNamedValue(FuncName)) return llvm::ConstantExpr::getBitCast(Func, VoidPtrTy); @@ -2153,14 +2138,16 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { CodeGenFunction::RunCleanupsScope cleanups(*this); - for (const auto &DestroyedCapture : DestroyedCaptures) { - const BlockDecl::Capture &CI = *DestroyedCapture.CI; - const CGBlockInfo::Capture &capture = *DestroyedCapture.Capture; - BlockFieldFlags flags = DestroyedCapture.DisposeFlags; + for (auto &capture : blockInfo.SortedCaptures) { + if (capture.isConstantOrTrivial()) + continue; + + const BlockDecl::Capture &CI = *capture.Cap; + BlockFieldFlags flags = capture.DisposeFlags; Address srcField = Builder.CreateStructGEP(src, capture.getIndex()); - pushCaptureCleanup(DestroyedCapture.DisposeKind, srcField, + pushCaptureCleanup(capture.DisposeKind, srcField, CI.getVariable()->getType(), flags, /*ForCopyHelper*/ false, CI.getVariable(), *this); } diff --git contrib/llvm-project/clang/lib/CodeGen/CGBlocks.h contrib/llvm-project/clang/lib/CodeGen/CGBlocks.h index 698ecd3d926a..e8857d98894f 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGBlocks.h +++ contrib/llvm-project/clang/lib/CodeGen/CGBlocks.h @@ -26,14 +26,7 @@ #include "clang/Basic/TargetInfo.h" namespace llvm { -class Constant; -class Function; -class GlobalValue; -class DataLayout; -class FunctionType; -class PointerType; class Value; -class LLVMContext; } namespace clang { @@ -148,6 +141,17 @@ public: CharUnits FieldOffset; }; +/// Represents a type of copy/destroy operation that should be performed for an +/// entity that's captured by a block. +enum class BlockCaptureEntityKind { + None, + CXXRecord, // Copy or destroy + ARCWeak, + ARCStrong, + NonTrivialCStruct, + BlockObject, // Assign or release +}; + /// CGBlockInfo - Information to generate a block literal. class CGBlockInfo { public: @@ -197,20 +201,40 @@ public: return FieldType; } - static Capture makeIndex(unsigned index, CharUnits offset, - QualType FieldType) { + static Capture + makeIndex(unsigned index, CharUnits offset, QualType FieldType, + BlockCaptureEntityKind CopyKind, BlockFieldFlags CopyFlags, + BlockCaptureEntityKind DisposeKind, BlockFieldFlags DisposeFlags, + const BlockDecl::Capture *Cap) { Capture v; v.Data = (index << 1) | 1; v.Offset = offset.getQuantity(); v.FieldType = FieldType; + v.CopyKind = CopyKind; + v.CopyFlags = CopyFlags; + v.DisposeKind = DisposeKind; + v.DisposeFlags = DisposeFlags; + v.Cap = Cap; return v; } - static Capture makeConstant(llvm::Value *value) { + static Capture makeConstant(llvm::Value *value, + const BlockDecl::Capture *Cap) { Capture v; v.Data = reinterpret_cast<uintptr_t>(value); + v.Cap = Cap; return v; } + + bool isConstantOrTrivial() const { + return CopyKind == BlockCaptureEntityKind::None && + DisposeKind == BlockCaptureEntityKind::None; + } + + BlockCaptureEntityKind CopyKind = BlockCaptureEntityKind::None, + DisposeKind = BlockCaptureEntityKind::None; + BlockFieldFlags CopyFlags, DisposeFlags; + const BlockDecl::Capture *Cap; }; /// CanBeGlobal - True if the block can be global, i.e. it has @@ -221,6 +245,9 @@ public: /// dispose helper functions if the block were escaping. bool NeedsCopyDispose : 1; + /// Indicates whether the block is non-escaping. + bool NoEscape : 1; + /// HasCXXObject - True if the block's custom copy/dispose functions /// need to be run even in GC mode. bool HasCXXObject : 1; @@ -238,8 +265,11 @@ public: /// functions. bool CapturesNonExternalType : 1; - /// The mapping of allocated indexes within the block. - llvm::DenseMap<const VarDecl*, Capture> Captures; + /// Mapping from variables to pointers to captures in SortedCaptures. + llvm::DenseMap<const VarDecl *, Capture *> Captures; + + /// The block's captures. Non-constant captures are sorted by their offsets. + llvm::SmallVector<Capture, 4> SortedCaptures; Address LocalAddress; llvm::StructType *StructureType; @@ -263,14 +293,18 @@ public: /// has been encountered. CGBlockInfo *NextBlockInfo; + void buildCaptureMap() { + for (auto &C : SortedCaptures) + Captures[C.Cap->getVariable()] = &C; + } + const Capture &getCapture(const VarDecl *var) const { return const_cast<CGBlockInfo*>(this)->getCapture(var); } Capture &getCapture(const VarDecl *var) { - llvm::DenseMap<const VarDecl*, Capture>::iterator - it = Captures.find(var); + auto it = Captures.find(var); assert(it != Captures.end() && "no entry for variable!"); - return it->second; + return *it->second; } const BlockDecl *getBlockDecl() const { return Block; } @@ -281,11 +315,6 @@ public: } CGBlockInfo(const BlockDecl *blockDecl, StringRef Name); - - // Indicates whether the block needs a custom copy or dispose function. - bool needsCopyDisposeHelpers() const { - return NeedsCopyDispose && !Block->doesNotEscape(); - } }; } // end namespace CodeGen diff --git contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp index 1982b40ff667..2b7862e618bd 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp @@ -159,6 +159,7 @@ static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V, static Value *MakeBinaryAtomicValue( CodeGenFunction &CGF, llvm::AtomicRMWInst::BinOp Kind, const CallExpr *E, AtomicOrdering Ordering = AtomicOrdering::SequentiallyConsistent) { + QualType T = E->getType(); assert(E->getArg(0)->getType()->isPointerType()); assert(CGF.getContext().hasSameUnqualifiedType(T, @@ -532,13 +533,13 @@ static Value *emitCallMaybeConstrainedFPBuiltin(CodeGenFunction &CGF, // Emit a simple mangled intrinsic that has 1 argument and a return type // matching the argument type. -static Value *emitUnaryBuiltin(CodeGenFunction &CGF, - const CallExpr *E, - unsigned IntrinsicID) { +static Value *emitUnaryBuiltin(CodeGenFunction &CGF, const CallExpr *E, + unsigned IntrinsicID, + llvm::StringRef Name = "") { llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); Function *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); - return CGF.Builder.CreateCall(F, Src0); + return CGF.Builder.CreateCall(F, Src0, Name); } // Emit an intrinsic that has 2 operands of the same type as its result. @@ -1060,7 +1061,10 @@ static llvm::Value *emitPPCLoadReserveIntrinsic(CodeGenFunction &CGF, llvm::InlineAsm *IA = llvm::InlineAsm::get(FTy, Asm, Constraints, /*hasSideEffects=*/true); - return CGF.Builder.CreateCall(IA, {Addr}); + llvm::CallInst *CI = CGF.Builder.CreateCall(IA, {Addr}); + CI->addParamAttr( + 0, Attribute::get(CGF.getLLVMContext(), Attribute::ElementType, RetType)); + return CI; } namespace { @@ -3122,24 +3126,34 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, } case Builtin::BI__builtin_elementwise_abs: { - Value *Op0 = EmitScalarExpr(E->getArg(0)); Value *Result; - if (Op0->getType()->isIntOrIntVectorTy()) + QualType QT = E->getArg(0)->getType(); + + if (auto *VecTy = QT->getAs<VectorType>()) + QT = VecTy->getElementType(); + if (QT->isIntegerType()) Result = Builder.CreateBinaryIntrinsic( - llvm::Intrinsic::abs, Op0, Builder.getFalse(), nullptr, "elt.abs"); + llvm::Intrinsic::abs, EmitScalarExpr(E->getArg(0)), + Builder.getFalse(), nullptr, "elt.abs"); else - Result = Builder.CreateUnaryIntrinsic(llvm::Intrinsic::fabs, Op0, nullptr, - "elt.abs"); - return RValue::get(Result); - } + Result = emitUnaryBuiltin(*this, E, llvm::Intrinsic::fabs, "elt.abs"); - case Builtin::BI__builtin_elementwise_ceil: { - Value *Op0 = EmitScalarExpr(E->getArg(0)); - Value *Result = Builder.CreateUnaryIntrinsic(llvm::Intrinsic::ceil, Op0, - nullptr, "elt.ceil"); return RValue::get(Result); } + case Builtin::BI__builtin_elementwise_ceil: + return RValue::get( + emitUnaryBuiltin(*this, E, llvm::Intrinsic::ceil, "elt.ceil")); + case Builtin::BI__builtin_elementwise_floor: + return RValue::get( + emitUnaryBuiltin(*this, E, llvm::Intrinsic::floor, "elt.floor")); + case Builtin::BI__builtin_elementwise_roundeven: + return RValue::get(emitUnaryBuiltin(*this, E, llvm::Intrinsic::roundeven, + "elt.roundeven")); + case Builtin::BI__builtin_elementwise_trunc: + return RValue::get( + emitUnaryBuiltin(*this, E, llvm::Intrinsic::trunc, "elt.trunc")); + case Builtin::BI__builtin_elementwise_max: { Value *Op0 = EmitScalarExpr(E->getArg(0)); Value *Op1 = EmitScalarExpr(E->getArg(1)); @@ -3174,52 +3188,48 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, } case Builtin::BI__builtin_reduce_max: { - auto GetIntrinsicID = [](QualType QT, llvm::Type *IrTy) { - if (IrTy->isIntOrIntVectorTy()) { - if (auto *VecTy = QT->getAs<VectorType>()) - QT = VecTy->getElementType(); - if (QT->isSignedIntegerType()) - return llvm::Intrinsic::vector_reduce_smax; - else - return llvm::Intrinsic::vector_reduce_umax; - } + auto GetIntrinsicID = [](QualType QT) { + if (auto *VecTy = QT->getAs<VectorType>()) + QT = VecTy->getElementType(); + if (QT->isSignedIntegerType()) + return llvm::Intrinsic::vector_reduce_smax; + if (QT->isUnsignedIntegerType()) + return llvm::Intrinsic::vector_reduce_umax; + assert(QT->isFloatingType() && "must have a float here"); return llvm::Intrinsic::vector_reduce_fmax; }; - Value *Op0 = EmitScalarExpr(E->getArg(0)); - Value *Result = Builder.CreateUnaryIntrinsic( - GetIntrinsicID(E->getArg(0)->getType(), Op0->getType()), Op0, nullptr, - "rdx.min"); - return RValue::get(Result); + return RValue::get(emitUnaryBuiltin( + *this, E, GetIntrinsicID(E->getArg(0)->getType()), "rdx.min")); } case Builtin::BI__builtin_reduce_min: { - auto GetIntrinsicID = [](QualType QT, llvm::Type *IrTy) { - if (IrTy->isIntOrIntVectorTy()) { - if (auto *VecTy = QT->getAs<VectorType>()) - QT = VecTy->getElementType(); - if (QT->isSignedIntegerType()) - return llvm::Intrinsic::vector_reduce_smin; - else - return llvm::Intrinsic::vector_reduce_umin; - } + auto GetIntrinsicID = [](QualType QT) { + if (auto *VecTy = QT->getAs<VectorType>()) + QT = VecTy->getElementType(); + if (QT->isSignedIntegerType()) + return llvm::Intrinsic::vector_reduce_smin; + if (QT->isUnsignedIntegerType()) + return llvm::Intrinsic::vector_reduce_umin; + assert(QT->isFloatingType() && "must have a float here"); return llvm::Intrinsic::vector_reduce_fmin; }; - Value *Op0 = EmitScalarExpr(E->getArg(0)); - Value *Result = Builder.CreateUnaryIntrinsic( - GetIntrinsicID(E->getArg(0)->getType(), Op0->getType()), Op0, nullptr, - "rdx.min"); - return RValue::get(Result); - } - case Builtin::BI__builtin_reduce_xor: { - Value *Op0 = EmitScalarExpr(E->getArg(0)); - Value *Result = Builder.CreateUnaryIntrinsic( - llvm::Intrinsic::vector_reduce_xor, Op0, nullptr, "rdx.xor"); - return RValue::get(Result); + return RValue::get(emitUnaryBuiltin( + *this, E, GetIntrinsicID(E->getArg(0)->getType()), "rdx.min")); } + case Builtin::BI__builtin_reduce_xor: + return RValue::get(emitUnaryBuiltin( + *this, E, llvm::Intrinsic::vector_reduce_xor, "rdx.xor")); + case Builtin::BI__builtin_reduce_or: + return RValue::get(emitUnaryBuiltin( + *this, E, llvm::Intrinsic::vector_reduce_or, "rdx.or")); + case Builtin::BI__builtin_reduce_and: + return RValue::get(emitUnaryBuiltin( + *this, E, llvm::Intrinsic::vector_reduce_and, "rdx.and")); + case Builtin::BI__builtin_matrix_transpose: { - const auto *MatrixTy = E->getArg(0)->getType()->getAs<ConstantMatrixType>(); + auto *MatrixTy = E->getArg(0)->getType()->castAs<ConstantMatrixType>(); Value *MatValue = EmitScalarExpr(E->getArg(0)); MatrixBuilder<CGBuilderTy> MB(Builder); Value *Result = MB.CreateMatrixTranspose(MatValue, MatrixTy->getNumRows(), @@ -3423,6 +3433,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BIalloca: case Builtin::BI_alloca: + case Builtin::BI__builtin_alloca_uninitialized: case Builtin::BI__builtin_alloca: { Value *Size = EmitScalarExpr(E->getArg(0)); const TargetInfo &TI = getContext().getTargetInfo(); @@ -3433,10 +3444,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, .getAsAlign(); AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); AI->setAlignment(SuitableAlignmentInBytes); - initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); + if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized) + initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); return RValue::get(AI); } + case Builtin::BI__builtin_alloca_with_align_uninitialized: case Builtin::BI__builtin_alloca_with_align: { Value *Size = EmitScalarExpr(E->getArg(0)); Value *AlignmentInBitsValue = EmitScalarExpr(E->getArg(1)); @@ -3446,7 +3459,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getAsAlign(); AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); AI->setAlignment(AlignmentInBytes); - initializeAlloca(*this, AI, Size, AlignmentInBytes); + if (BuiltinID != Builtin::BI__builtin_alloca_with_align_uninitialized) + initializeAlloca(*this, AI, Size, AlignmentInBytes); return RValue::get(AI); } @@ -4921,7 +4935,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, llvm::Value *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); - AttrBuilder B; + AttrBuilder B(Builder.getContext()); B.addByValAttr(NDRangeL.getAddress(*this).getElementType()); llvm::AttributeList ByValAttrSet = llvm::AttributeList::get(CGM.getModule().getContext(), 3U, B); @@ -5860,6 +5874,10 @@ static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = { NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType), NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType), NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType), + NEONMAP1(vqrdmlah_v, arm_neon_vqrdmlah, Add1ArgType), + NEONMAP1(vqrdmlahq_v, arm_neon_vqrdmlah, Add1ArgType), + NEONMAP1(vqrdmlsh_v, arm_neon_vqrdmlsh, Add1ArgType), + NEONMAP1(vqrdmlshq_v, arm_neon_vqrdmlsh, Add1ArgType), NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType), NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType), NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), @@ -6085,6 +6103,10 @@ static const ARMVectorIntrinsicInfo AArch64SIMDIntrinsicMap[] = { NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType), NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType), NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType), + NEONMAP1(vqrdmlah_v, aarch64_neon_sqrdmlah, Add1ArgType), + NEONMAP1(vqrdmlahq_v, aarch64_neon_sqrdmlah, Add1ArgType), + NEONMAP1(vqrdmlsh_v, aarch64_neon_sqrdmlsh, Add1ArgType), + NEONMAP1(vqrdmlshq_v, aarch64_neon_sqrdmlsh, Add1ArgType), NEONMAP1(vqrdmulh_lane_v, aarch64_neon_sqrdmulh_lane, 0), NEONMAP1(vqrdmulh_laneq_v, aarch64_neon_sqrdmulh_laneq, 0), NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType), @@ -6287,6 +6309,10 @@ static const ARMVectorIntrinsicInfo AArch64SISDIntrinsicMap[] = { NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType), NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType), + NEONMAP1(vqrdmlahh_s16, aarch64_neon_sqrdmlah, Vectorize1ArgType | Use64BitVectors), + NEONMAP1(vqrdmlahs_s32, aarch64_neon_sqrdmlah, Add1ArgType), + NEONMAP1(vqrdmlshh_s16, aarch64_neon_sqrdmlsh, Vectorize1ArgType | Use64BitVectors), + NEONMAP1(vqrdmlshs_s32, aarch64_neon_sqrdmlsh, Add1ArgType), NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors), NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType), NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), @@ -14271,73 +14297,6 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, return Builder.CreateCall(F, Ops[0]); } } - case X86::BI__builtin_ia32_pabsb128: - case X86::BI__builtin_ia32_pabsw128: - case X86::BI__builtin_ia32_pabsd128: - case X86::BI__builtin_ia32_pabsb256: - case X86::BI__builtin_ia32_pabsw256: - case X86::BI__builtin_ia32_pabsd256: - case X86::BI__builtin_ia32_pabsq128: - case X86::BI__builtin_ia32_pabsq256: - case X86::BI__builtin_ia32_pabsb512: - case X86::BI__builtin_ia32_pabsw512: - case X86::BI__builtin_ia32_pabsd512: - case X86::BI__builtin_ia32_pabsq512: { - Function *F = CGM.getIntrinsic(Intrinsic::abs, Ops[0]->getType()); - return Builder.CreateCall(F, {Ops[0], Builder.getInt1(false)}); - } - case X86::BI__builtin_ia32_pmaxsb128: - case X86::BI__builtin_ia32_pmaxsw128: - case X86::BI__builtin_ia32_pmaxsd128: - case X86::BI__builtin_ia32_pmaxsq128: - case X86::BI__builtin_ia32_pmaxsb256: - case X86::BI__builtin_ia32_pmaxsw256: - case X86::BI__builtin_ia32_pmaxsd256: - case X86::BI__builtin_ia32_pmaxsq256: - case X86::BI__builtin_ia32_pmaxsb512: - case X86::BI__builtin_ia32_pmaxsw512: - case X86::BI__builtin_ia32_pmaxsd512: - case X86::BI__builtin_ia32_pmaxsq512: - return EmitX86BinaryIntrinsic(*this, Ops, Intrinsic::smax); - case X86::BI__builtin_ia32_pmaxub128: - case X86::BI__builtin_ia32_pmaxuw128: - case X86::BI__builtin_ia32_pmaxud128: - case X86::BI__builtin_ia32_pmaxuq128: - case X86::BI__builtin_ia32_pmaxub256: - case X86::BI__builtin_ia32_pmaxuw256: - case X86::BI__builtin_ia32_pmaxud256: - case X86::BI__builtin_ia32_pmaxuq256: - case X86::BI__builtin_ia32_pmaxub512: - case X86::BI__builtin_ia32_pmaxuw512: - case X86::BI__builtin_ia32_pmaxud512: - case X86::BI__builtin_ia32_pmaxuq512: - return EmitX86BinaryIntrinsic(*this, Ops, Intrinsic::umax); - case X86::BI__builtin_ia32_pminsb128: - case X86::BI__builtin_ia32_pminsw128: - case X86::BI__builtin_ia32_pminsd128: - case X86::BI__builtin_ia32_pminsq128: - case X86::BI__builtin_ia32_pminsb256: - case X86::BI__builtin_ia32_pminsw256: - case X86::BI__builtin_ia32_pminsd256: - case X86::BI__builtin_ia32_pminsq256: - case X86::BI__builtin_ia32_pminsb512: - case X86::BI__builtin_ia32_pminsw512: - case X86::BI__builtin_ia32_pminsd512: - case X86::BI__builtin_ia32_pminsq512: - return EmitX86BinaryIntrinsic(*this, Ops, Intrinsic::smin); - case X86::BI__builtin_ia32_pminub128: - case X86::BI__builtin_ia32_pminuw128: - case X86::BI__builtin_ia32_pminud128: - case X86::BI__builtin_ia32_pminuq128: - case X86::BI__builtin_ia32_pminub256: - case X86::BI__builtin_ia32_pminuw256: - case X86::BI__builtin_ia32_pminud256: - case X86::BI__builtin_ia32_pminuq256: - case X86::BI__builtin_ia32_pminub512: - case X86::BI__builtin_ia32_pminuw512: - case X86::BI__builtin_ia32_pminud512: - case X86::BI__builtin_ia32_pminuq512: - return EmitX86BinaryIntrinsic(*this, Ops, Intrinsic::umin); case X86::BI__builtin_ia32_pmuludq128: case X86::BI__builtin_ia32_pmuludq256: @@ -14418,12 +14377,6 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, CGM.getIntrinsic(Intrinsic::vector_reduce_add, Ops[0]->getType()); return Builder.CreateCall(F, {Ops[0]}); } - case X86::BI__builtin_ia32_reduce_and_d512: - case X86::BI__builtin_ia32_reduce_and_q512: { - Function *F = - CGM.getIntrinsic(Intrinsic::vector_reduce_and, Ops[0]->getType()); - return Builder.CreateCall(F, {Ops[0]}); - } case X86::BI__builtin_ia32_reduce_fadd_pd512: case X86::BI__builtin_ia32_reduce_fadd_ps512: case X86::BI__builtin_ia32_reduce_fadd_ph512: @@ -14470,36 +14423,6 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, CGM.getIntrinsic(Intrinsic::vector_reduce_mul, Ops[0]->getType()); return Builder.CreateCall(F, {Ops[0]}); } - case X86::BI__builtin_ia32_reduce_or_d512: - case X86::BI__builtin_ia32_reduce_or_q512: { - Function *F = - CGM.getIntrinsic(Intrinsic::vector_reduce_or, Ops[0]->getType()); - return Builder.CreateCall(F, {Ops[0]}); - } - case X86::BI__builtin_ia32_reduce_smax_d512: - case X86::BI__builtin_ia32_reduce_smax_q512: { - Function *F = - CGM.getIntrinsic(Intrinsic::vector_reduce_smax, Ops[0]->getType()); - return Builder.CreateCall(F, {Ops[0]}); - } - case X86::BI__builtin_ia32_reduce_smin_d512: - case X86::BI__builtin_ia32_reduce_smin_q512: { - Function *F = - CGM.getIntrinsic(Intrinsic::vector_reduce_smin, Ops[0]->getType()); - return Builder.CreateCall(F, {Ops[0]}); - } - case X86::BI__builtin_ia32_reduce_umax_d512: - case X86::BI__builtin_ia32_reduce_umax_q512: { - Function *F = - CGM.getIntrinsic(Intrinsic::vector_reduce_umax, Ops[0]->getType()); - return Builder.CreateCall(F, {Ops[0]}); - } - case X86::BI__builtin_ia32_reduce_umin_d512: - case X86::BI__builtin_ia32_reduce_umin_q512: { - Function *F = - CGM.getIntrinsic(Intrinsic::vector_reduce_umin, Ops[0]->getType()); - return Builder.CreateCall(F, {Ops[0]}); - } // 3DNow! case X86::BI__builtin_ia32_pswapdsf: @@ -17279,7 +17202,7 @@ static NVPTXMmaLdstInfo getNVPTXMmaLdstInfo(unsigned BuiltinID) { case NVPTX::BI__mma_tf32_m16n16k8_ld_a: return MMA_LDST(4, m16n16k8_load_a_tf32); case NVPTX::BI__mma_tf32_m16n16k8_ld_b: - return MMA_LDST(2, m16n16k8_load_b_tf32); + return MMA_LDST(4, m16n16k8_load_b_tf32); case NVPTX::BI__mma_tf32_m16n16k8_ld_c: return MMA_LDST(8, m16n16k8_load_c_f32); @@ -18448,15 +18371,11 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, llvm_unreachable("unexpected builtin ID"); } llvm::Type *SrcT = Vec->getType(); - llvm::Type *TruncT = - SrcT->getWithNewType(llvm::IntegerType::get(getLLVMContext(), 32)); + llvm::Type *TruncT = SrcT->getWithNewType(Builder.getInt32Ty()); Function *Callee = CGM.getIntrinsic(IntNo, {TruncT, SrcT}); Value *Trunc = Builder.CreateCall(Callee, Vec); - Value *Splat = Builder.CreateVectorSplat(2, Builder.getInt32(0)); - Value *ConcatMask = - llvm::ConstantVector::get({Builder.getInt32(0), Builder.getInt32(1), - Builder.getInt32(2), Builder.getInt32(3)}); - return Builder.CreateShuffleVector(Trunc, Splat, ConcatMask); + Value *Splat = Constant::getNullValue(TruncT); + return Builder.CreateShuffleVector(Trunc, Splat, ArrayRef<int>{0, 1, 2, 3}); } case WebAssembly::BI__builtin_wasm_shuffle_i8x16: { Value *Ops[18]; @@ -18822,6 +18741,8 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_bcompress_64: case RISCV::BI__builtin_riscv_bdecompress_32: case RISCV::BI__builtin_riscv_bdecompress_64: + case RISCV::BI__builtin_riscv_bfp_32: + case RISCV::BI__builtin_riscv_bfp_64: case RISCV::BI__builtin_riscv_grev_32: case RISCV::BI__builtin_riscv_grev_64: case RISCV::BI__builtin_riscv_gorc_32: @@ -18841,7 +18762,11 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_crc32c_b: case RISCV::BI__builtin_riscv_crc32c_h: case RISCV::BI__builtin_riscv_crc32c_w: - case RISCV::BI__builtin_riscv_crc32c_d: { + case RISCV::BI__builtin_riscv_crc32c_d: + case RISCV::BI__builtin_riscv_fsl_32: + case RISCV::BI__builtin_riscv_fsr_32: + case RISCV::BI__builtin_riscv_fsl_64: + case RISCV::BI__builtin_riscv_fsr_64: { switch (BuiltinID) { default: llvm_unreachable("unexpected builtin ID"); // Zbb @@ -18871,6 +18796,12 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, ID = Intrinsic::riscv_bdecompress; break; + // Zbf + case RISCV::BI__builtin_riscv_bfp_32: + case RISCV::BI__builtin_riscv_bfp_64: + ID = Intrinsic::riscv_bfp; + break; + // Zbp case RISCV::BI__builtin_riscv_grev_32: case RISCV::BI__builtin_riscv_grev_64: @@ -18926,6 +18857,16 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_crc32c_d: ID = Intrinsic::riscv_crc32c_d; break; + + // Zbt + case RISCV::BI__builtin_riscv_fsl_32: + case RISCV::BI__builtin_riscv_fsl_64: + ID = Intrinsic::riscv_fsl; + break; + case RISCV::BI__builtin_riscv_fsr_32: + case RISCV::BI__builtin_riscv_fsr_64: + ID = Intrinsic::riscv_fsr; + break; } IntrinsicTypes = {ResultType}; diff --git contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp index 9714730e3c4b..0b441e382f11 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp @@ -154,6 +154,51 @@ void CGCXXABI::setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr) { CGF.CXXABIThisValue = ThisPtr; } +bool CGCXXABI::mayNeedDestruction(const VarDecl *VD) const { + if (VD->needsDestruction(getContext())) + return true; + + // If the variable has an incomplete class type (or array thereof), it + // might need destruction. + const Type *T = VD->getType()->getBaseElementTypeUnsafe(); + if (T->getAs<RecordType>() && T->isIncompleteType()) + return true; + + return false; +} + +bool CGCXXABI::isEmittedWithConstantInitializer( + const VarDecl *VD, bool InspectInitForWeakDef) const { + VD = VD->getMostRecentDecl(); + if (VD->hasAttr<ConstInitAttr>()) + return true; + + // All later checks examine the initializer specified on the variable. If + // the variable is weak, such examination would not be correct. + if (!InspectInitForWeakDef && (VD->isWeak() || VD->hasAttr<SelectAnyAttr>())) + return false; + + const VarDecl *InitDecl = VD->getInitializingDeclaration(); + if (!InitDecl) + return false; + + // If there's no initializer to run, this is constant initialization. + if (!InitDecl->hasInit()) + return true; + + // If we have the only definition, we don't need a thread wrapper if we + // will emit the value as a constant. + if (isUniqueGVALinkage(getContext().GetGVALinkageForVariable(VD))) + return !mayNeedDestruction(VD) && InitDecl->evaluateValue(); + + // Otherwise, we need a thread wrapper unless we know that every + // translation unit will emit the value as a constant. We rely on the + // variable being constant-initialized in every translation unit if it's + // constant-initialized in any translation unit, which isn't actually + // guaranteed by the standard but is necessary for sanity. + return InitDecl->hasConstantInitialization(); +} + void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResultType) { assert(!CGF.hasAggregateEvaluationKind(ResultType) && diff --git contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.h contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.h index ea839db7528e..b96222b3ce28 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.h +++ contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.h @@ -31,7 +31,6 @@ class CXXConstructorDecl; class CXXDestructorDecl; class CXXMethodDecl; class CXXRecordDecl; -class FieldDecl; class MangleContext; namespace CodeGen { @@ -80,6 +79,18 @@ protected: ASTContext &getContext() const { return CGM.getContext(); } + bool mayNeedDestruction(const VarDecl *VD) const; + + /// Determine whether we will definitely emit this variable with a constant + /// initializer, either because the language semantics demand it or because + /// we know that the initializer is a constant. + // For weak definitions, any initializer available in the current translation + // is not necessarily reflective of the initializer used; such initializers + // are ignored unless if InspectInitForWeakDef is true. + bool + isEmittedWithConstantInitializer(const VarDecl *VD, + bool InspectInitForWeakDef = false) const; + virtual bool requiresArrayCookie(const CXXDeleteExpr *E, QualType eltType); virtual bool requiresArrayCookie(const CXXNewExpr *E); diff --git contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp index d70f78fea6b4..a37ff8844e88 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp @@ -1892,7 +1892,7 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name, } void CodeGenModule::addDefaultFunctionDefinitionAttributes(llvm::Function &F) { - llvm::AttrBuilder FuncAttrs; + llvm::AttrBuilder FuncAttrs(F.getContext()); getDefaultFunctionAttributes(F.getName(), F.hasOptNone(), /* AttrOnCallSite = */ false, FuncAttrs); // TODO: call GetCPUAndFeaturesAttributes? @@ -2014,8 +2014,8 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite, bool IsThunk) { - llvm::AttrBuilder FuncAttrs; - llvm::AttrBuilder RetAttrs; + llvm::AttrBuilder FuncAttrs(getLLVMContext()); + llvm::AttrBuilder RetAttrs(getLLVMContext()); // Collect function IR attributes from the CC lowering. // We'll collect the paramete and result attributes later. @@ -2243,7 +2243,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, getLangOpts().Sanitize.has(SanitizerKind::Return); // Determine if the return type could be partially undef - if (CodeGenOpts.EnableNoundefAttrs && HasStrictReturn) { + if (!CodeGenOpts.DisableNoundefAttrs && HasStrictReturn) { if (!RetTy->isVoidType() && RetAI.getKind() != ABIArgInfo::Indirect && DetermineNoUndef(RetTy, getTypes(), DL, RetAI)) RetAttrs.addAttribute(llvm::Attribute::NoUndef); @@ -2302,7 +2302,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, // Attach attributes to sret. if (IRFunctionArgs.hasSRetArg()) { - llvm::AttrBuilder SRETAttrs; + llvm::AttrBuilder SRETAttrs(getLLVMContext()); SRETAttrs.addStructRetAttr(getTypes().ConvertTypeForMem(RetTy)); hasUsedSRet = true; if (RetAI.getInReg()) @@ -2314,7 +2314,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, // Attach attributes to inalloca argument. if (IRFunctionArgs.hasInallocaArg()) { - llvm::AttrBuilder Attrs; + llvm::AttrBuilder Attrs(getLLVMContext()); Attrs.addInAllocaAttr(FI.getArgStruct()); ArgAttrs[IRFunctionArgs.getInallocaArgNo()] = llvm::AttributeSet::get(getLLVMContext(), Attrs); @@ -2329,7 +2329,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, assert(IRArgs.second == 1 && "Expected only a single `this` pointer."); - llvm::AttrBuilder Attrs; + llvm::AttrBuilder Attrs(getLLVMContext()); QualType ThisTy = FI.arg_begin()->type.castAs<PointerType>()->getPointeeType(); @@ -2364,7 +2364,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, I != E; ++I, ++ArgNo) { QualType ParamType = I->type; const ABIArgInfo &AI = I->info; - llvm::AttrBuilder Attrs; + llvm::AttrBuilder Attrs(getLLVMContext()); // Add attribute for padding argument, if necessary. if (IRFunctionArgs.hasPaddingArg(ArgNo)) { @@ -2372,14 +2372,15 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)] = llvm::AttributeSet::get( getLLVMContext(), - llvm::AttrBuilder().addAttribute(llvm::Attribute::InReg)); + llvm::AttrBuilder(getLLVMContext()).addAttribute(llvm::Attribute::InReg)); } } // Decide whether the argument we're handling could be partially undef - bool ArgNoUndef = DetermineNoUndef(ParamType, getTypes(), DL, AI); - if (CodeGenOpts.EnableNoundefAttrs && ArgNoUndef) + if (!CodeGenOpts.DisableNoundefAttrs && + DetermineNoUndef(ParamType, getTypes(), DL, AI)) { Attrs.addAttribute(llvm::Attribute::NoUndef); + } // 'restrict' -> 'noalias' is done in EmitFunctionProlog when we // have the corresponding parameter variable. It doesn't make @@ -2519,8 +2520,8 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, unsigned FirstIRArg, NumIRArgs; std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo); for (unsigned i = 0; i < NumIRArgs; i++) - ArgAttrs[FirstIRArg + i] = - llvm::AttributeSet::get(getLLVMContext(), Attrs); + ArgAttrs[FirstIRArg + i] = ArgAttrs[FirstIRArg + i].addAttributes( + getLLVMContext(), llvm::AttributeSet::get(getLLVMContext(), Attrs)); } } assert(ArgNo == FI.arg_size()); @@ -2747,11 +2748,11 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, QualType ETy = ArrTy->getElementType(); llvm::Align Alignment = CGM.getNaturalTypeAlignment(ETy).getAsAlign(); - AI->addAttrs(llvm::AttrBuilder().addAlignmentAttr(Alignment)); + AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(Alignment)); uint64_t ArrSize = ArrTy->getSize().getZExtValue(); if (!ETy->isIncompleteType() && ETy->isConstantSizeType() && ArrSize) { - llvm::AttrBuilder Attrs; + llvm::AttrBuilder Attrs(getLLVMContext()); Attrs.addDereferenceableAttr( getContext().getTypeSizeInChars(ETy).getQuantity() * ArrSize); @@ -2771,7 +2772,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, QualType ETy = ArrTy->getElementType(); llvm::Align Alignment = CGM.getNaturalTypeAlignment(ETy).getAsAlign(); - AI->addAttrs(llvm::AttrBuilder().addAlignmentAttr(Alignment)); + AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(Alignment)); if (!getContext().getTargetAddressSpace(ETy) && !CGM.getCodeGenOpts().NullPointerIsValid) AI->addAttr(llvm::Attribute::NonNull); @@ -2793,7 +2794,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment); if (AI->getParamAlign().valueOrOne() < AlignmentInt) { AI->removeAttr(llvm::Attribute::AttrKind::Alignment); - AI->addAttrs(llvm::AttrBuilder().addAlignmentAttr( + AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr( llvm::Align(AlignmentInt))); } } @@ -3879,9 +3880,8 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, } // Create the temporary. - Address temp = CGF.CreateTempAlloca(destType->getElementType(), - CGF.getPointerAlign(), - "icr.temp"); + Address temp = CGF.CreateTempAlloca(destType->getPointerElementType(), + CGF.getPointerAlign(), "icr.temp"); // Loading an l-value can introduce a cleanup if the l-value is __weak, // and that cleanup will be conditional if we can't prove that the l-value // isn't null, so we need to register a dominating point so that the cleanups @@ -3891,9 +3891,8 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, // Zero-initialize it if we're not doing a copy-initialization. bool shouldCopy = CRE->shouldCopy(); if (!shouldCopy) { - llvm::Value *null = - llvm::ConstantPointerNull::get( - cast<llvm::PointerType>(destType->getElementType())); + llvm::Value *null = llvm::ConstantPointerNull::get( + cast<llvm::PointerType>(destType->getPointerElementType())); CGF.Builder.CreateStore(null, temp); } @@ -3935,7 +3934,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, assert(srcRV.isScalar()); llvm::Value *src = srcRV.getScalarVal(); - src = CGF.Builder.CreateBitCast(src, destType->getElementType(), + src = CGF.Builder.CreateBitCast(src, destType->getPointerElementType(), "icr.cast"); // Use an ordinary store, not a store-to-lvalue. @@ -5074,8 +5073,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, #ifndef NDEBUG // Assert that these structs have equivalent element types. llvm::StructType *FullTy = CallInfo.getArgStruct(); - llvm::StructType *DeclaredTy = cast<llvm::StructType>( - cast<llvm::PointerType>(LastParamTy)->getElementType()); + llvm::StructType *DeclaredTy = + cast<llvm::StructType>(LastParamTy->getPointerElementType()); assert(DeclaredTy->getNumElements() == FullTy->getNumElements()); for (llvm::StructType::element_iterator DI = DeclaredTy->element_begin(), DE = DeclaredTy->element_end(), diff --git contrib/llvm-project/clang/lib/CodeGen/CGCall.h contrib/llvm-project/clang/lib/CodeGen/CGCall.h index c8594068c3fc..af63e1bddd2d 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGCall.h +++ contrib/llvm-project/clang/lib/CodeGen/CGCall.h @@ -26,17 +26,13 @@ #include "ABIInfo.h" namespace llvm { -class AttributeList; -class Function; class Type; class Value; } // namespace llvm namespace clang { -class ASTContext; class Decl; class FunctionDecl; -class ObjCMethodDecl; class VarDecl; namespace CodeGen { @@ -49,11 +45,11 @@ class CGCalleeInfo { GlobalDecl CalleeDecl; public: - explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl() {} + explicit CGCalleeInfo() : CalleeProtoTy(nullptr) {} CGCalleeInfo(const FunctionProtoType *calleeProtoTy, GlobalDecl calleeDecl) : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {} CGCalleeInfo(const FunctionProtoType *calleeProtoTy) - : CalleeProtoTy(calleeProtoTy), CalleeDecl() {} + : CalleeProtoTy(calleeProtoTy) {} CGCalleeInfo(GlobalDecl calleeDecl) : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {} @@ -116,7 +112,8 @@ public: assert(functionPtr && "configuring callee without function pointer"); assert(functionPtr->getType()->isPointerTy()); assert(functionPtr->getType()->isOpaquePointerTy() || - functionPtr->getType()->getPointerElementType()->isFunctionTy()); + functionPtr->getType()->getNonOpaquePointerElementType() + ->isFunctionTy()); } static CGCallee forBuiltin(unsigned builtinID, diff --git contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp index 8f99ff0d50ff..520e119ada26 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp @@ -390,7 +390,7 @@ Address CodeGenFunction::GetAddressOfBaseClass( llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2, "cast.result"); PHI->addIncoming(Value.getPointer(), notNullBB); PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB); - Value = Address(PHI, Value.getAlignment()); + Value = Value.withPointer(PHI); } return Value; @@ -1983,7 +1983,7 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, CharUnits eltAlignment = arrayBase.getAlignment() .alignmentOfArrayElement(getContext().getTypeSizeInChars(type)); - Address curAddr = Address(cur, eltAlignment); + Address curAddr = Address(cur, elementType, eltAlignment); // Zero initialize the storage, if requested. if (zeroInitialize) @@ -2852,9 +2852,8 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad( SanitizerHandler::CFICheckFail, {}, {}); } - return Builder.CreateBitCast( - Builder.CreateExtractValue(CheckedLoad, 0), - cast<llvm::PointerType>(VTable->getType())->getElementType()); + return Builder.CreateBitCast(Builder.CreateExtractValue(CheckedLoad, 0), + VTable->getType()->getPointerElementType()); } void CodeGenFunction::EmitForwardingCallToLambda( diff --git contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h index 76f3a48f32f3..079a3e25d6dc 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h +++ contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h @@ -23,7 +23,6 @@ namespace llvm { class BasicBlock; class Value; class ConstantInt; -class AllocaInst; } namespace clang { diff --git contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp index 2041d2a5b4c9..c1763cbbc5a0 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp @@ -707,6 +707,10 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) { if (Stmt *Ret = S.getReturnStmt()) EmitStmt(Ret); + + // LLVM require the frontend to add the function attribute. See + // Coroutines.rst. + CurFn->addFnAttr("coroutine.presplit", "0"); } // Emit coroutine intrinsic and patch up arguments of the token type. diff --git contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp index 6e189a61dd20..1a9080604a79 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp @@ -354,13 +354,9 @@ CGDebugInfo::computeChecksum(FileID FID, SmallString<32> &Checksum) const { if (!MemBuffer) return None; - llvm::MD5 Hash; - llvm::MD5::MD5Result Result; - - Hash.update(MemBuffer->getBuffer()); - Hash.final(Result); - - Hash.stringifyResult(Result, Checksum); + llvm::toHex( + llvm::MD5::hash(llvm::arrayRefFromStringRef(MemBuffer->getBuffer())), + /*LowerCase*/ true, Checksum); return llvm::DIFile::CSK_MD5; } @@ -722,7 +718,7 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { auto *LowerBound = llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned( llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0)); - SmallVector<int64_t, 9> Expr( + SmallVector<uint64_t, 9> Expr( {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx, /* AArch64::VG */ 46, 0, llvm::dwarf::DW_OP_mul, llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus}); @@ -768,7 +764,7 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { } // Element count = (VLENB / SEW) x LMUL - SmallVector<int64_t, 12> Expr( + SmallVector<uint64_t, 12> Expr( // The DW_OP_bregx operation has two operands: a register which is // specified by an unsigned LEB128 number, followed by a signed LEB128 // offset. @@ -3690,7 +3686,7 @@ void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD, const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) { // Seek non-virtual primary base root. - while (1) { + while (true) { const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase); const CXXRecordDecl *PBT = BRL.getPrimaryBase(); if (PBT && !BRL.isPrimaryBaseVirtual()) @@ -4325,7 +4321,7 @@ void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) { } void CGDebugInfo::AppendAddressSpaceXDeref( - unsigned AddressSpace, SmallVectorImpl<int64_t> &Expr) const { + unsigned AddressSpace, SmallVectorImpl<uint64_t> &Expr) const { Optional<unsigned> DWARFAddressSpace = CGM.getTarget().getDWARFAddressSpace(AddressSpace); if (!DWARFAddressSpace) @@ -4494,7 +4490,7 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD, Line = getLineNumber(VD->getLocation()); Column = getColumnNumber(VD->getLocation()); } - SmallVector<int64_t, 13> Expr; + SmallVector<uint64_t, 13> Expr; llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; if (VD->isImplicit()) Flags |= llvm::DINode::FlagArtificial; @@ -4720,7 +4716,7 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable( target.getStructLayout(blockInfo.StructureType) ->getElementOffset(blockInfo.getCapture(VD).getIndex())); - SmallVector<int64_t, 9> addr; + SmallVector<uint64_t, 9> addr; addr.push_back(llvm::dwarf::DW_OP_deref); addr.push_back(llvm::dwarf::DW_OP_plus_uconst); addr.push_back(offset.getQuantity()); @@ -5191,7 +5187,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, } else { auto Align = getDeclAlignIfRequired(D, CGM.getContext()); - SmallVector<int64_t, 4> Expr; + SmallVector<uint64_t, 4> Expr; unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(D->getType()); if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) { diff --git contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h index 14ff0eeabd21..a76426e585c8 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h +++ contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h @@ -40,7 +40,6 @@ class ClassTemplateSpecializationDecl; class GlobalDecl; class ModuleMap; class ObjCInterfaceDecl; -class ObjCIvarDecl; class UsingDecl; class VarDecl; enum class DynamicInitKind : unsigned; @@ -363,7 +362,7 @@ class CGDebugInfo { /// Extended dereferencing mechanism is has the following format: /// DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef void AppendAddressSpaceXDeref(unsigned AddressSpace, - SmallVectorImpl<int64_t> &Expr) const; + SmallVectorImpl<uint64_t> &Expr) const; /// A helper function to collect debug info for the default elements of a /// block. diff --git contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp index e09279c1d455..18d658436086 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp @@ -1392,9 +1392,11 @@ void CodeGenFunction::EmitAndRegisterVariableArrayDimensions( else { // Create an artificial VarDecl to generate debug info for. IdentifierInfo *NameIdent = VLAExprNames[NameIdx++]; - auto VlaExprTy = VlaSize.NumElts->getType()->getPointerElementType(); + assert(cast<llvm::PointerType>(VlaSize.NumElts->getType()) + ->isOpaqueOrPointeeTypeMatches(SizeTy) && + "Number of VLA elements must be SizeTy"); auto QT = getContext().getIntTypeForBitwidth( - VlaExprTy->getScalarSizeInBits(), false); + SizeTy->getScalarSizeInBits(), false); auto *ArtificialDecl = VarDecl::Create( getContext(), const_cast<DeclContext *>(D.getDeclContext()), D.getLocation(), D.getLocation(), NameIdent, QT, @@ -2250,16 +2252,17 @@ void CodeGenFunction::emitArrayDestroy(llvm::Value *begin, // Shift the address back by one element. llvm::Value *negativeOne = llvm::ConstantInt::get(SizeTy, -1, true); + llvm::Type *llvmElementType = ConvertTypeForMem(elementType); llvm::Value *element = Builder.CreateInBoundsGEP( - elementPast->getType()->getPointerElementType(), elementPast, negativeOne, - "arraydestroy.element"); + llvmElementType, elementPast, negativeOne, "arraydestroy.element"); if (useEHCleanup) pushRegularPartialArrayCleanup(begin, element, elementType, elementAlign, destroyer); // Perform the actual destruction there. - destroyer(*this, Address(element, elementAlign), elementType); + destroyer(*this, Address(element, llvmElementType, elementAlign), + elementType); if (useEHCleanup) PopCleanupBlock(); diff --git contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp index 3579761f1429..7b880c1354e1 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp @@ -136,6 +136,7 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, } // Otherwise, the standard logic requires a helper function. } else { + Addr = Addr.getElementBitCast(CGF.ConvertTypeForMem(Type)); Func = CodeGenFunction(CGM) .generateDestroyHelper(Addr, Type, CGF.getDestroyer(DtorKind), CGF.needsEHCleanup(DtorKind), &D); diff --git contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp index 34b4951a7f72..0fb7ec26a85e 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp @@ -1931,7 +1931,7 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, SourceLocation Loc) { if (LV.isMatrixElt()) { llvm::Value *Idx = LV.getMatrixIdx(); if (CGM.getCodeGenOpts().OptimizationLevel > 0) { - const auto *const MatTy = LV.getType()->getAs<ConstantMatrixType>(); + const auto *const MatTy = LV.getType()->castAs<ConstantMatrixType>(); llvm::MatrixBuilder<CGBuilderTy> MB(Builder); MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened()); } @@ -2077,7 +2077,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, if (Dst.isMatrixElt()) { llvm::Value *Idx = Dst.getMatrixIdx(); if (CGM.getCodeGenOpts().OptimizationLevel > 0) { - const auto *const MatTy = Dst.getType()->getAs<ConstantMatrixType>(); + const auto *const MatTy = Dst.getType()->castAs<ConstantMatrixType>(); llvm::MatrixBuilder<CGBuilderTy> MB(Builder); MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened()); } @@ -3178,7 +3178,7 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF, bool MayReturn = !IsFatal || RecoverKind == CheckRecoverableKind::AlwaysRecoverable; - llvm::AttrBuilder B; + llvm::AttrBuilder B(CGF.getLLVMContext()); if (!MayReturn) { B.addAttribute(llvm::Attribute::NoReturn) .addAttribute(llvm::Attribute::NoUnwind); @@ -4699,12 +4699,9 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { if (LV.isSimple()) { Address V = LV.getAddress(*this); if (V.isValid()) { - llvm::Type *T = - ConvertTypeForMem(E->getType()) - ->getPointerTo( - cast<llvm::PointerType>(V.getType())->getAddressSpace()); - if (V.getType() != T) - LV.setAddress(Builder.CreateBitCast(V, T)); + llvm::Type *T = ConvertTypeForMem(E->getType()); + if (V.getElementType() != T) + LV.setAddress(Builder.CreateElementBitCast(V, T)); } } return LV; @@ -4763,8 +4760,9 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { CGM.EmitExplicitCastExprType(CE, this); LValue LV = EmitLValue(E->getSubExpr()); - Address V = Builder.CreateBitCast(LV.getAddress(*this), - ConvertType(CE->getTypeAsWritten())); + Address V = Builder.CreateElementBitCast( + LV.getAddress(*this), + ConvertTypeForMem(CE->getTypeAsWritten()->getPointeeType())); if (SanOpts.has(SanitizerKind::CFIUnrelatedCast)) EmitVTablePtrCheckForCast(E->getType(), V.getPointer(), diff --git contrib/llvm-project/clang/lib/CodeGen/CGExprAgg.cpp contrib/llvm-project/clang/lib/CodeGen/CGExprAgg.cpp index 3b996b89a1d7..0968afd82064 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGExprAgg.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGExprAgg.cpp @@ -614,8 +614,8 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, // every temporary created in a default argument is sequenced before // the construction of the next array element, if any CodeGenFunction::RunCleanupsScope CleanupsScope(CGF); - LValue elementLV = - CGF.MakeAddrLValue(Address(currentElement, elementAlign), elementType); + LValue elementLV = CGF.MakeAddrLValue( + Address(currentElement, llvmElementType, elementAlign), elementType); if (filler) EmitInitializationToLValue(filler, elementLV); else @@ -1801,6 +1801,7 @@ void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E, CharUnits elementSize = CGF.getContext().getTypeSizeInChars(elementType); CharUnits elementAlign = destPtr.getAlignment().alignmentOfArrayElement(elementSize); + llvm::Type *llvmElementType = CGF.ConvertTypeForMem(elementType); llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body"); @@ -1810,8 +1811,8 @@ void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E, llvm::PHINode *index = Builder.CreatePHI(zero->getType(), 2, "arrayinit.index"); index->addIncoming(zero, entryBB); - llvm::Value *element = Builder.CreateInBoundsGEP( - begin->getType()->getPointerElementType(), begin, index); + llvm::Value *element = + Builder.CreateInBoundsGEP(llvmElementType, begin, index); // Prepare for a cleanup. QualType::DestructionKind dtorKind = elementType.isDestructedType(); diff --git contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp index e32462eb635c..4e8933fffe03 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp @@ -1613,8 +1613,9 @@ ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) { if (GlobalConstStr->getType()->getPointerAddressSpace() == ExprAS) return GlobalConstStr; - llvm::Type *EltTy = GlobalConstStr->getType()->getPointerElementType(); - llvm::PointerType *NewPtrTy = llvm::PointerType::get(EltTy, ExprAS); + llvm::PointerType *PtrTy = cast<llvm::PointerType>(GlobalConstStr->getType()); + llvm::PointerType *NewPtrTy = + llvm::PointerType::getWithSamePointeeType(PtrTy, ExprAS); return Builder.CreateAddrSpaceCast(GlobalConstStr, NewPtrTy, "usn_addr_cast"); } diff --git contrib/llvm-project/clang/lib/CodeGen/CGObjC.cpp contrib/llvm-project/clang/lib/CodeGen/CGObjC.cpp index b5bcf157036d..8cc609186f9e 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGObjC.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGObjC.cpp @@ -847,7 +847,7 @@ static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar, static bool hasUnalignedAtomics(llvm::Triple::ArchType arch) { // FIXME: Allow unaligned atomic load/store on x86. (It is not // currently supported by the backend.) - return 0; + return false; } /// Return the maximum size that permits atomic accesses for the given diff --git contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp index b2bf60d2c0fc..52b449090868 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp @@ -2347,9 +2347,10 @@ llvm::Value *CGObjCGNU::GetTypedSelector(CodeGenFunction &CGF, Selector Sel, } } if (!SelValue) { - SelValue = llvm::GlobalAlias::create( - SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage, - ".objc_selector_" + Sel.getAsString(), &TheModule); + SelValue = llvm::GlobalAlias::create(SelectorTy->getPointerElementType(), 0, + llvm::GlobalValue::PrivateLinkage, + ".objc_selector_" + Sel.getAsString(), + &TheModule); Types.emplace_back(TypeEncoding, SelValue); } @@ -2576,14 +2577,16 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF, if (IsClassMessage) { if (!MetaClassPtrAlias) { MetaClassPtrAlias = llvm::GlobalAlias::create( - IdTy->getElementType(), 0, llvm::GlobalValue::InternalLinkage, + IdTy->getPointerElementType(), 0, + llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" + Class->getNameAsString(), &TheModule); } ReceiverClass = MetaClassPtrAlias; } else { if (!ClassPtrAlias) { ClassPtrAlias = llvm::GlobalAlias::create( - IdTy->getElementType(), 0, llvm::GlobalValue::InternalLinkage, + IdTy->getPointerElementType(), 0, + llvm::GlobalValue::InternalLinkage, ".objc_class_ref" + Class->getNameAsString(), &TheModule); } ReceiverClass = ClassPtrAlias; @@ -3706,7 +3709,7 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() { GenerateProtocolHolderCategory(); llvm::StructType *selStructTy = - dyn_cast<llvm::StructType>(SelectorTy->getElementType()); + dyn_cast<llvm::StructType>(SelectorTy->getPointerElementType()); llvm::Type *selStructPtrTy = SelectorTy; if (!selStructTy) { selStructTy = llvm::StructType::get(CGM.getLLVMContext(), diff --git contrib/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp contrib/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp index 425d1a793439..e7dba4c8feab 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp @@ -2138,16 +2138,7 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, const ObjCCommonTypesHelper &ObjCTypes) { CodeGenTypes &Types = CGM.getTypes(); auto selTy = CGF.getContext().getObjCSelType(); - llvm::Value *SelValue; - - if (Method && Method->isDirectMethod()) { - // Direct methods will synthesize the proper `_cmd` internally, - // so just don't bother with setting the `_cmd` argument. - assert(!IsSuper); - SelValue = llvm::UndefValue::get(Types.ConvertType(selTy)); - } else { - SelValue = GetSelector(CGF, Sel); - } + llvm::Value *SelValue = llvm::UndefValue::get(Types.ConvertType(selTy)); CallArgList ActualArgs; if (!IsSuper) @@ -2168,10 +2159,15 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, canMessageReceiverBeNull(CGF, Method, IsSuper, ClassReceiver, Arg0); bool RequiresNullCheck = false; + bool RequiresSelValue = true; llvm::FunctionCallee Fn = nullptr; if (Method && Method->isDirectMethod()) { + assert(!IsSuper); Fn = GenerateDirectMethod(Method, Method->getClassInterface()); + // Direct methods will synthesize the proper `_cmd` internally, + // so just don't bother with setting the `_cmd` argument. + RequiresSelValue = false; } else if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) { if (ReceiverCanBeNull) RequiresNullCheck = true; Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper) @@ -2209,6 +2205,12 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, nullReturn.init(CGF, Arg0); } + // If a selector value needs to be passed, emit the load before the call. + if (RequiresSelValue) { + SelValue = GetSelector(CGF, Sel); + ActualArgs[1] = CallArg(RValue::get(SelValue), selTy); + } + llvm::CallBase *CallSite; CGCallee Callee = CGCallee::forDirect(BitcastFn); RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, @@ -2487,7 +2489,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, if (FQT->isUnionType()) HasUnion = true; - BuildRCBlockVarRecordLayout(FQT->getAs<RecordType>(), + BuildRCBlockVarRecordLayout(FQT->castAs<RecordType>(), BytePos + FieldOffset, HasUnion); continue; } @@ -2935,8 +2937,7 @@ CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM, const CGBlockInfo &blockInfo) { fillRunSkipBlockVars(CGM, blockInfo); - return getBlockLayoutInfoString(RunSkipBlockVars, - blockInfo.needsCopyDisposeHelpers()); + return getBlockLayoutInfoString(RunSkipBlockVars, blockInfo.NeedsCopyDispose); } llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM, @@ -4370,7 +4371,11 @@ FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) { void FragileHazards::emitWriteHazard() { if (Locals.empty()) return; - CGF.EmitNounwindRuntimeCall(WriteHazard, Locals); + llvm::CallInst *Call = CGF.EmitNounwindRuntimeCall(WriteHazard, Locals); + for (auto Pair : llvm::enumerate(Locals)) + Call->addParamAttr(Pair.index(), llvm::Attribute::get( + CGF.getLLVMContext(), llvm::Attribute::ElementType, + cast<llvm::AllocaInst>(Pair.value())->getAllocatedType())); } void FragileHazards::emitReadHazard(CGBuilderTy &Builder) { @@ -4378,6 +4383,10 @@ void FragileHazards::emitReadHazard(CGBuilderTy &Builder) { llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals); call->setDoesNotThrow(); call->setCallingConv(CGF.getRuntimeCC()); + for (auto Pair : llvm::enumerate(Locals)) + call->addParamAttr(Pair.index(), llvm::Attribute::get( + Builder.getContext(), llvm::Attribute::ElementType, + cast<llvm::AllocaInst>(Pair.value())->getAllocatedType())); } /// Emit read hazards in all the protected blocks, i.e. all the blocks diff --git contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp index e35c15421520..db1c3ca191ca 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -837,12 +837,11 @@ void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N) { } llvm::Value *Size; llvm::Value *SizeInChars; - auto *ElemType = - cast<llvm::PointerType>(OrigAddresses[N].first.getPointer(CGF)->getType()) - ->getElementType(); + auto *ElemType = OrigAddresses[N].first.getAddress(CGF).getElementType(); auto *ElemSizeOf = llvm::ConstantExpr::getSizeOf(ElemType); if (AsArraySection) { - Size = CGF.Builder.CreatePtrDiff(OrigAddresses[N].second.getPointer(CGF), + Size = CGF.Builder.CreatePtrDiff(ElemType, + OrigAddresses[N].second.getPointer(CGF), OrigAddresses[N].first.getPointer(CGF)); Size = CGF.Builder.CreateNUWAdd( Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1)); @@ -1008,7 +1007,8 @@ Address ReductionCodeGen::adjustPrivateAddress(CodeGenFunction &CGF, unsigned N, OriginalBaseLValue); Address SharedAddr = SharedAddresses[N].first.getAddress(CGF); llvm::Value *Adjustment = CGF.Builder.CreatePtrDiff( - BaseLValue.getPointer(CGF), SharedAddr.getPointer()); + SharedAddr.getElementType(), BaseLValue.getPointer(CGF), + SharedAddr.getPointer()); llvm::Value *PrivatePointer = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( PrivateAddr.getPointer(), SharedAddr.getType()); @@ -1429,24 +1429,25 @@ static StringRef getIdentStringFromSourceLocation(CodeGenFunction &CGF, llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc, unsigned Flags) { + uint32_t SrcLocStrSize; llvm::Constant *SrcLocStr; if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo || Loc.isInvalid()) { - SrcLocStr = OMPBuilder.getOrCreateDefaultSrcLocStr(); + SrcLocStr = OMPBuilder.getOrCreateDefaultSrcLocStr(SrcLocStrSize); } else { - std::string FunctionName = ""; + std::string FunctionName; if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) FunctionName = FD->getQualifiedNameAsString(); PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc); const char *FileName = PLoc.getFilename(); unsigned Line = PLoc.getLine(); unsigned Column = PLoc.getColumn(); - SrcLocStr = - OMPBuilder.getOrCreateSrcLocStr(FunctionName, FileName, Line, Column); + SrcLocStr = OMPBuilder.getOrCreateSrcLocStr(FunctionName, FileName, Line, + Column, SrcLocStrSize); } unsigned Reserved2Flags = getDefaultLocationReserved2Flags(); - return OMPBuilder.getOrCreateIdent(SrcLocStr, llvm::omp::IdentFlag(Flags), - Reserved2Flags); + return OMPBuilder.getOrCreateIdent( + SrcLocStr, SrcLocStrSize, llvm::omp::IdentFlag(Flags), Reserved2Flags); } llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF, @@ -1457,10 +1458,11 @@ llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF, if (CGM.getLangOpts().OpenMPIRBuilder) { SmallString<128> Buffer; OMPBuilder.updateToLocation(CGF.Builder.saveIP()); + uint32_t SrcLocStrSize; auto *SrcLocStr = OMPBuilder.getOrCreateSrcLocStr( - getIdentStringFromSourceLocation(CGF, Loc, Buffer)); + getIdentStringFromSourceLocation(CGF, Loc, Buffer), SrcLocStrSize); return OMPBuilder.getOrCreateThreadID( - OMPBuilder.getOrCreateIdent(SrcLocStr)); + OMPBuilder.getOrCreateIdent(SrcLocStr, SrcLocStrSize)); } llvm::Value *ThreadID = nullptr; @@ -3464,8 +3466,7 @@ static bool isAllocatableDecl(const VarDecl *VD) { return false; const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>(); // Use the default allocation. - return !((AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc || - AA->getAllocatorType() == OMPAllocateDeclAttr::OMPNullMemAlloc) && + return !(AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc && !AA->getAllocator()); } @@ -8120,7 +8121,7 @@ private: .getAddress(CGF); } Size = CGF.Builder.CreatePtrDiff( - CGF.EmitCastToVoidPtr(ComponentLB.getPointer()), + CGF.Int8Ty, CGF.EmitCastToVoidPtr(ComponentLB.getPointer()), CGF.EmitCastToVoidPtr(LB.getPointer())); break; } @@ -8141,7 +8142,7 @@ private: CombinedInfo.BasePointers.push_back(BP.getPointer()); CombinedInfo.Pointers.push_back(LB.getPointer()); Size = CGF.Builder.CreatePtrDiff( - CGF.Builder.CreateConstGEP(HB, 1).getPointer(), + CGF.Int8Ty, CGF.Builder.CreateConstGEP(HB, 1).getPointer(), CGF.EmitCastToVoidPtr(LB.getPointer())); CombinedInfo.Sizes.push_back( CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true)); @@ -8967,7 +8968,7 @@ public: CGF.Builder.CreateConstGEP1_32(HBAddr.getElementType(), HB, /*Idx0=*/1); llvm::Value *CLAddr = CGF.Builder.CreatePointerCast(LB, CGF.VoidPtrTy); llvm::Value *CHAddr = CGF.Builder.CreatePointerCast(HAddr, CGF.VoidPtrTy); - llvm::Value *Diff = CGF.Builder.CreatePtrDiff(CHAddr, CLAddr); + llvm::Value *Diff = CGF.Builder.CreatePtrDiff(CGF.Int8Ty, CHAddr, CLAddr); llvm::Value *Size = CGF.Builder.CreateIntCast(Diff, CGF.Int64Ty, /*isSigned=*/false); CombinedInfo.Sizes.push_back(Size); @@ -9527,8 +9528,9 @@ llvm::Constant * emitMappingInformation(CodeGenFunction &CGF, llvm::OpenMPIRBuilder &OMPBuilder, MappableExprsHandler::MappingExprInfo &MapExprs) { + uint32_t SrcLocStrSize; if (!MapExprs.getMapDecl() && !MapExprs.getMapExpr()) - return OMPBuilder.getOrCreateDefaultSrcLocStr(); + return OMPBuilder.getOrCreateDefaultSrcLocStr(SrcLocStrSize); SourceLocation Loc; if (!MapExprs.getMapDecl() && MapExprs.getMapExpr()) { @@ -9540,7 +9542,7 @@ emitMappingInformation(CodeGenFunction &CGF, llvm::OpenMPIRBuilder &OMPBuilder, Loc = MapExprs.getMapDecl()->getLocation(); } - std::string ExprName = ""; + std::string ExprName; if (MapExprs.getMapExpr()) { PrintingPolicy P(CGF.getContext().getLangOpts()); llvm::raw_string_ostream OS(ExprName); @@ -9551,8 +9553,9 @@ emitMappingInformation(CodeGenFunction &CGF, llvm::OpenMPIRBuilder &OMPBuilder, } PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc); - return OMPBuilder.getOrCreateSrcLocStr(PLoc.getFilename(), ExprName.c_str(), - PLoc.getLine(), PLoc.getColumn()); + return OMPBuilder.getOrCreateSrcLocStr(PLoc.getFilename(), ExprName, + PLoc.getLine(), PLoc.getColumn(), + SrcLocStrSize); } /// Emit the arrays used to pass the captures and map information to the @@ -10216,8 +10219,7 @@ void CGOpenMPRuntime::emitUDMapperArrayInitOrDel( llvm::Value *Cond; if (IsInit) { // base != begin? - llvm::Value *BaseIsBegin = MapperCGF.Builder.CreateIsNotNull( - MapperCGF.Builder.CreatePtrDiff(Base, Begin)); + llvm::Value *BaseIsBegin = MapperCGF.Builder.CreateICmpNE(Base, Begin); // IsPtrAndObj? llvm::Value *PtrAndObjBit = MapperCGF.Builder.CreateAnd( MapType, @@ -10581,7 +10583,7 @@ void CGOpenMPRuntime::emitTargetCall( emitOffloadingArraysArgument( CGF, Info.BasePointersArray, Info.PointersArray, Info.SizesArray, Info.MapTypesArray, Info.MapNamesArray, Info.MappersArray, Info, - {/*ForEndTask=*/false}); + {/*ForEndCall=*/false}); InputInfo.NumberOfTargetItems = Info.NumberOfPtrs; InputInfo.BasePointersArray = @@ -11463,7 +11465,7 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall( emitOffloadingArraysArgument( CGF, Info.BasePointersArray, Info.PointersArray, Info.SizesArray, Info.MapTypesArray, Info.MapNamesArray, Info.MappersArray, Info, - {/*ForEndTask=*/false}); + {/*ForEndCall=*/false}); InputInfo.NumberOfTargetItems = Info.NumberOfPtrs; InputInfo.BasePointersArray = Address(Info.BasePointersArray, CGM.getPointerAlign()); @@ -12213,6 +12215,26 @@ Address CGOpenMPRuntime::getParameterAddress(CodeGenFunction &CGF, return CGF.GetAddrOfLocalVar(NativeParam); } +/// Return allocator value from expression, or return a null allocator (default +/// when no allocator specified). +static llvm::Value *getAllocatorVal(CodeGenFunction &CGF, + const Expr *Allocator) { + llvm::Value *AllocVal; + if (Allocator) { + AllocVal = CGF.EmitScalarExpr(Allocator); + // According to the standard, the original allocator type is a enum + // (integer). Convert to pointer type, if required. + AllocVal = CGF.EmitScalarConversion(AllocVal, Allocator->getType(), + CGF.getContext().VoidPtrTy, + Allocator->getExprLoc()); + } else { + // If no allocator specified, it defaults to the null allocator. + AllocVal = llvm::Constant::getNullValue( + CGF.CGM.getTypes().ConvertType(CGF.getContext().VoidPtrTy)); + } + return AllocVal; +} + Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD) { if (!VD) @@ -12249,20 +12271,24 @@ Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF, } llvm::Value *ThreadID = getThreadID(CGF, CVD->getBeginLoc()); const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>(); - assert(AA->getAllocator() && - "Expected allocator expression for non-default allocator."); - llvm::Value *Allocator = CGF.EmitScalarExpr(AA->getAllocator()); - // According to the standard, the original allocator type is a enum - // (integer). Convert to pointer type, if required. - Allocator = CGF.EmitScalarConversion( - Allocator, AA->getAllocator()->getType(), CGF.getContext().VoidPtrTy, - AA->getAllocator()->getExprLoc()); - llvm::Value *Args[] = {ThreadID, Size, Allocator}; - - llvm::Value *Addr = - CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_alloc), - Args, getName({CVD->getName(), ".void.addr"})); + const Expr *Allocator = AA->getAllocator(); + llvm::Value *AllocVal = getAllocatorVal(CGF, Allocator); + llvm::Value *Alignment = + AA->getAlignment() + ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(AA->getAlignment()), + CGM.SizeTy, /*isSigned=*/false) + : nullptr; + SmallVector<llvm::Value *, 4> Args; + Args.push_back(ThreadID); + if (Alignment) + Args.push_back(Alignment); + Args.push_back(Size); + Args.push_back(AllocVal); + llvm::omp::RuntimeFunction FnID = + Alignment ? OMPRTL___kmpc_aligned_alloc : OMPRTL___kmpc_alloc; + llvm::Value *Addr = CGF.EmitRuntimeCall( + OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), FnID), Args, + getName({CVD->getName(), ".void.addr"})); llvm::FunctionCallee FiniRTLFn = OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_free); QualType Ty = CGM.getContext().getPointerType(CVD->getType()); @@ -12276,14 +12302,14 @@ Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF, llvm::FunctionCallee RTLFn; SourceLocation::UIntTy LocEncoding; Address Addr; - const Expr *Allocator; + const Expr *AllocExpr; public: OMPAllocateCleanupTy(llvm::FunctionCallee RTLFn, SourceLocation::UIntTy LocEncoding, Address Addr, - const Expr *Allocator) + const Expr *AllocExpr) : RTLFn(RTLFn), LocEncoding(LocEncoding), Addr(Addr), - Allocator(Allocator) {} + AllocExpr(AllocExpr) {} void Emit(CodeGenFunction &CGF, Flags /*flags*/) override { if (!CGF.HaveInsertPoint()) return; @@ -12292,14 +12318,8 @@ Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF, CGF, SourceLocation::getFromRawEncoding(LocEncoding)); Args[1] = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( Addr.getPointer(), CGF.VoidPtrTy); - llvm::Value *AllocVal = CGF.EmitScalarExpr(Allocator); - // According to the standard, the original allocator type is a enum - // (integer). Convert to pointer type, if required. - AllocVal = CGF.EmitScalarConversion(AllocVal, Allocator->getType(), - CGF.getContext().VoidPtrTy, - Allocator->getExprLoc()); + llvm::Value *AllocVal = getAllocatorVal(CGF, AllocExpr); Args[2] = AllocVal; - CGF.EmitRuntimeCall(RTLFn, Args); } }; @@ -12307,7 +12327,7 @@ Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF, UntiedRealAddr.isValid() ? UntiedRealAddr : Address(Addr, Align); CGF.EHStack.pushCleanup<OMPAllocateCleanupTy>( NormalAndEHCleanup, FiniRTLFn, CVD->getLocation().getRawEncoding(), - VDAddr, AA->getAllocator()); + VDAddr, Allocator); if (UntiedRealAddr.isValid()) if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) diff --git contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.h contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.h index b83ec78696d1..19754b0cfacc 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.h +++ contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -35,7 +35,6 @@ class ArrayType; class Constant; class FunctionType; class GlobalVariable; -class StructType; class Type; class Value; class OpenMPIRBuilder; @@ -48,7 +47,6 @@ class OMPExecutableDirective; class OMPLoopDirective; class VarDecl; class OMPDeclareReductionDecl; -class IdentifierInfo; namespace CodeGen { class Address; diff --git contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index 866454ddeaed..e09ea5e01b1a 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -1402,10 +1402,14 @@ void CGOpenMPRuntimeGPU::emitGenericVarsProlog(CodeGenFunction &CGF, // Allocate space for the variable to be globalized llvm::Value *AllocArgs[] = {CGF.getTypeSize(VD->getType())}; - llvm::Instruction *VoidPtr = + llvm::CallBase *VoidPtr = CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_alloc_shared), AllocArgs, VD->getName()); + // FIXME: We should use the variables actual alignment as an argument. + VoidPtr->addRetAttr(llvm::Attribute::get( + CGM.getLLVMContext(), llvm::Attribute::Alignment, + CGM.getContext().getTargetInfo().getNewAlign() / 8)); // Cast the void pointer and get the address of the globalized variable. llvm::PointerType *VarPtrTy = CGF.ConvertTypeForMem(VarTy)->getPointerTo(); @@ -1438,10 +1442,13 @@ void CGOpenMPRuntimeGPU::emitGenericVarsProlog(CodeGenFunction &CGF, // Allocate space for this VLA object to be globalized. llvm::Value *AllocArgs[] = {CGF.getTypeSize(VD->getType())}; - llvm::Instruction *VoidPtr = + llvm::CallBase *VoidPtr = CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_alloc_shared), AllocArgs, VD->getName()); + VoidPtr->addRetAttr( + llvm::Attribute::get(CGM.getLLVMContext(), llvm::Attribute::Alignment, + CGM.getContext().getTargetInfo().getNewAlign())); I->getSecond().EscapedVariableLengthDeclsAddrs.emplace_back( std::pair<llvm::Value *, llvm::Value *>( @@ -1791,8 +1798,9 @@ static void shuffleAndStore(CodeGenFunction &CGF, Address SrcAddr, Ptr = Address(PhiSrc, Ptr.getAlignment()); ElemPtr = Address(PhiDest, ElemPtr.getAlignment()); llvm::Value *PtrDiff = Bld.CreatePtrDiff( - PtrEnd.getPointer(), Bld.CreatePointerBitCastOrAddrSpaceCast( - Ptr.getPointer(), CGF.VoidPtrTy)); + CGF.Int8Ty, PtrEnd.getPointer(), + Bld.CreatePointerBitCastOrAddrSpaceCast(Ptr.getPointer(), + CGF.VoidPtrTy)); Bld.CreateCondBr(Bld.CreateICmpSGT(PtrDiff, Bld.getInt64(IntSize - 1)), ThenBB, ExitBB); CGF.EmitBlock(ThenBB); @@ -3394,12 +3402,13 @@ CGOpenMPRuntimeGPU::getParameterAddress(CodeGenFunction &CGF, LocalAddr, /*Volatile=*/false, TargetTy, SourceLocation()); // First cast to generic. TargetAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - TargetAddr, TargetAddr->getType()->getPointerElementType()->getPointerTo( - /*AddrSpace=*/0)); + TargetAddr, llvm::PointerType::getWithSamePointeeType( + cast<llvm::PointerType>(TargetAddr->getType()), /*AddrSpace=*/0)); // Cast from generic to native address space. TargetAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - TargetAddr, TargetAddr->getType()->getPointerElementType()->getPointerTo( - NativePointeeAddrSpace)); + TargetAddr, llvm::PointerType::getWithSamePointeeType( + cast<llvm::PointerType>(TargetAddr->getType()), + NativePointeeAddrSpace)); Address NativeParamAddr = CGF.CreateMemTemp(NativeParamType); CGF.EmitStoreOfScalar(TargetAddr, NativeParamAddr, /*Volatile=*/false, NativeParamType); @@ -3424,8 +3433,8 @@ void CGOpenMPRuntimeGPU::emitOutlinedFunctionCall( continue; } llvm::Value *TargetArg = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - NativeArg, - NativeArg->getType()->getPointerElementType()->getPointerTo()); + NativeArg, llvm::PointerType::getWithSamePointeeType( + cast<llvm::PointerType>(NativeArg->getType()), /*AddrSpace*/ 0)); TargetArgs.emplace_back( CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(TargetArg, TargetType)); } diff --git contrib/llvm-project/clang/lib/CodeGen/CGRecordLayout.h contrib/llvm-project/clang/lib/CodeGen/CGRecordLayout.h index e6665b72bcba..5a3bcdf72f7b 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGRecordLayout.h +++ contrib/llvm-project/clang/lib/CodeGen/CGRecordLayout.h @@ -93,8 +93,8 @@ struct CGBitFieldInfo { CharUnits VolatileStorageOffset; CGBitFieldInfo() - : Offset(), Size(), IsSigned(), StorageSize(), StorageOffset(), - VolatileOffset(), VolatileStorageSize(), VolatileStorageOffset() {} + : Offset(), Size(), IsSigned(), StorageSize(), VolatileOffset(), + VolatileStorageSize() {} CGBitFieldInfo(unsigned Offset, unsigned Size, bool IsSigned, unsigned StorageSize, CharUnits StorageOffset) diff --git contrib/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp contrib/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index cf8313f92587..6f85bca8a201 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -411,7 +411,7 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field, continue; } llvm::Type *Type = - Types.ConvertTypeForMem(Field->getType(), /*ForBitFields=*/true); + Types.ConvertTypeForMem(Field->getType(), /*ForBitField=*/true); // If we don't have a run yet, or don't live within the previous run's // allocated storage then we allocate some storage and start a new run. if (Run == FieldEnd || BitOffset >= Tail) { diff --git contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp index ef0068cd3b0c..520483bc08b6 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp @@ -2109,42 +2109,35 @@ AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, return (EarlyClobber ? "&{" : "{") + Register.str() + "}"; } -llvm::Value* -CodeGenFunction::EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, - LValue InputValue, QualType InputType, - std::string &ConstraintStr, - SourceLocation Loc) { - llvm::Value *Arg; +std::pair<llvm::Value*, llvm::Type *> CodeGenFunction::EmitAsmInputLValue( + const TargetInfo::ConstraintInfo &Info, LValue InputValue, + QualType InputType, std::string &ConstraintStr, SourceLocation Loc) { if (Info.allowsRegister() || !Info.allowsMemory()) { - if (CodeGenFunction::hasScalarEvaluationKind(InputType)) { - Arg = EmitLoadOfLValue(InputValue, Loc).getScalarVal(); - } else { - llvm::Type *Ty = ConvertType(InputType); - uint64_t Size = CGM.getDataLayout().getTypeSizeInBits(Ty); - if ((Size <= 64 && llvm::isPowerOf2_64(Size)) || - getTargetHooks().isScalarizableAsmOperand(*this, Ty)) { - Ty = llvm::IntegerType::get(getLLVMContext(), Size); - Ty = llvm::PointerType::getUnqual(Ty); - - Arg = Builder.CreateLoad( - Builder.CreateBitCast(InputValue.getAddress(*this), Ty)); - } else { - Arg = InputValue.getPointer(*this); - ConstraintStr += '*'; - } + if (CodeGenFunction::hasScalarEvaluationKind(InputType)) + return {EmitLoadOfLValue(InputValue, Loc).getScalarVal(), nullptr}; + + llvm::Type *Ty = ConvertType(InputType); + uint64_t Size = CGM.getDataLayout().getTypeSizeInBits(Ty); + if ((Size <= 64 && llvm::isPowerOf2_64(Size)) || + getTargetHooks().isScalarizableAsmOperand(*this, Ty)) { + Ty = llvm::IntegerType::get(getLLVMContext(), Size); + Ty = llvm::PointerType::getUnqual(Ty); + + return {Builder.CreateLoad( + Builder.CreateBitCast(InputValue.getAddress(*this), Ty)), + nullptr}; } - } else { - Arg = InputValue.getPointer(*this); - ConstraintStr += '*'; } - return Arg; + Address Addr = InputValue.getAddress(*this); + ConstraintStr += '*'; + return {Addr.getPointer(), Addr.getElementType()}; } -llvm::Value* CodeGenFunction::EmitAsmInput( - const TargetInfo::ConstraintInfo &Info, - const Expr *InputExpr, - std::string &ConstraintStr) { +std::pair<llvm::Value *, llvm::Type *> +CodeGenFunction::EmitAsmInput(const TargetInfo::ConstraintInfo &Info, + const Expr *InputExpr, + std::string &ConstraintStr) { // If this can't be a register or memory, i.e., has to be a constant // (immediate or symbolic), try to emit it as such. if (!Info.allowsRegister() && !Info.allowsMemory()) { @@ -2155,19 +2148,20 @@ llvm::Value* CodeGenFunction::EmitAsmInput( llvm::APSInt IntResult; if (EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), getContext())) - return llvm::ConstantInt::get(getLLVMContext(), IntResult); + return {llvm::ConstantInt::get(getLLVMContext(), IntResult), nullptr}; } Expr::EvalResult Result; if (InputExpr->EvaluateAsInt(Result, getContext())) - return llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt()); + return {llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt()), + nullptr}; } if (Info.allowsRegister() || !Info.allowsMemory()) if (CodeGenFunction::hasScalarEvaluationKind(InputExpr->getType())) - return EmitScalarExpr(InputExpr); + return {EmitScalarExpr(InputExpr), nullptr}; if (InputExpr->getStmtClass() == Expr::CXXThisExprClass) - return EmitScalarExpr(InputExpr); + return {EmitScalarExpr(InputExpr), nullptr}; InputExpr = InputExpr->IgnoreParenNoopCasts(getContext()); LValue Dest = EmitLValue(InputExpr); return EmitAsmInputLValue(Info, Dest, InputExpr->getType(), ConstraintStr, @@ -2209,6 +2203,7 @@ static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect, bool HasUnwindClobber, bool ReadOnly, bool ReadNone, bool NoMerge, const AsmStmt &S, const std::vector<llvm::Type *> &ResultRegTypes, + const std::vector<llvm::Type *> &ArgElemTypes, CodeGenFunction &CGF, std::vector<llvm::Value *> &RegResults) { if (!HasUnwindClobber) @@ -2224,6 +2219,15 @@ static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect, Result.addFnAttr(llvm::Attribute::ReadOnly); } + // Add elementtype attribute for indirect constraints. + for (auto Pair : llvm::enumerate(ArgElemTypes)) { + if (Pair.value()) { + auto Attr = llvm::Attribute::get( + CGF.getLLVMContext(), llvm::Attribute::ElementType, Pair.value()); + Result.addParamAttr(Pair.index(), Attr); + } + } + // Slap the source location of the inline asm into a !srcloc metadata on the // call. if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S)) @@ -2291,6 +2295,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { std::vector<llvm::Type *> ResultRegTypes; std::vector<llvm::Type *> ResultTruncRegTypes; std::vector<llvm::Type *> ArgTypes; + std::vector<llvm::Type *> ArgElemTypes; std::vector<llvm::Value*> Args; llvm::BitVector ResultTypeRequiresCast; @@ -2298,6 +2303,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { std::string InOutConstraints; std::vector<llvm::Value*> InOutArgs; std::vector<llvm::Type*> InOutArgTypes; + std::vector<llvm::Type*> InOutArgElemTypes; // Keep track of out constraints for tied input operand. std::vector<std::string> OutputConstraints; @@ -2399,21 +2405,19 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { std::max((uint64_t)LargestVectorWidth, VT->getPrimitiveSizeInBits().getKnownMinSize()); } else { - llvm::Type *DestAddrTy = Dest.getAddress(*this).getType(); - llvm::Value *DestPtr = Dest.getPointer(*this); + Address DestAddr = Dest.getAddress(*this); // Matrix types in memory are represented by arrays, but accessed through // vector pointers, with the alignment specified on the access operation. // For inline assembly, update pointer arguments to use vector pointers. // Otherwise there will be a mis-match if the matrix is also an // input-argument which is represented as vector. - if (isa<MatrixType>(OutExpr->getType().getCanonicalType())) { - DestAddrTy = llvm::PointerType::get( - ConvertType(OutExpr->getType()), - cast<llvm::PointerType>(DestAddrTy)->getAddressSpace()); - DestPtr = Builder.CreateBitCast(DestPtr, DestAddrTy); - } - ArgTypes.push_back(DestAddrTy); - Args.push_back(DestPtr); + if (isa<MatrixType>(OutExpr->getType().getCanonicalType())) + DestAddr = Builder.CreateElementBitCast( + DestAddr, ConvertType(OutExpr->getType())); + + ArgTypes.push_back(DestAddr.getType()); + ArgElemTypes.push_back(DestAddr.getElementType()); + Args.push_back(DestAddr.getPointer()); Constraints += "=*"; Constraints += OutputConstraint; ReadOnly = ReadNone = false; @@ -2423,9 +2427,11 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { InOutConstraints += ','; const Expr *InputExpr = S.getOutputExpr(i); - llvm::Value *Arg = EmitAsmInputLValue(Info, Dest, InputExpr->getType(), - InOutConstraints, - InputExpr->getExprLoc()); + llvm::Value *Arg; + llvm::Type *ArgElemType; + std::tie(Arg, ArgElemType) = EmitAsmInputLValue( + Info, Dest, InputExpr->getType(), InOutConstraints, + InputExpr->getExprLoc()); if (llvm::Type* AdjTy = getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, @@ -2444,6 +2450,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { InOutConstraints += OutputConstraint; InOutArgTypes.push_back(Arg->getType()); + InOutArgElemTypes.push_back(ArgElemType); InOutArgs.push_back(Arg); } } @@ -2483,7 +2490,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { getTarget(), CGM, S, false /* No EarlyClobber */); std::string ReplaceConstraint (InputConstraint); - llvm::Value *Arg = EmitAsmInput(Info, InputExpr, Constraints); + llvm::Value *Arg; + llvm::Type *ArgElemType; + std::tie(Arg, ArgElemType) = EmitAsmInput(Info, InputExpr, Constraints); // If this input argument is tied to a larger output result, extend the // input to be the same size as the output. The LLVM backend wants to see @@ -2528,10 +2537,19 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { VT->getPrimitiveSizeInBits().getKnownMinSize()); ArgTypes.push_back(Arg->getType()); + ArgElemTypes.push_back(ArgElemType); Args.push_back(Arg); Constraints += InputConstraint; } + // Append the "input" part of inout constraints. + for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { + ArgTypes.push_back(InOutArgTypes[i]); + ArgElemTypes.push_back(InOutArgElemTypes[i]); + Args.push_back(InOutArgs[i]); + } + Constraints += InOutConstraints; + // Labels SmallVector<llvm::BasicBlock *, 16> Transfer; llvm::BasicBlock *Fallthrough = nullptr; @@ -2546,21 +2564,15 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { llvm::BlockAddress::get(CurFn, Dest.getBlock()); Args.push_back(BA); ArgTypes.push_back(BA->getType()); + ArgElemTypes.push_back(nullptr); if (!Constraints.empty()) Constraints += ','; - Constraints += 'X'; + Constraints += 'i'; } Fallthrough = createBasicBlock("asm.fallthrough"); } } - // Append the "input" part of inout constraints last. - for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { - ArgTypes.push_back(InOutArgTypes[i]); - Args.push_back(InOutArgs[i]); - } - Constraints += InOutConstraints; - bool HasUnwindClobber = false; // Clobbers @@ -2647,18 +2659,18 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { EmitBlock(Fallthrough); UpdateAsmCallInst(cast<llvm::CallBase>(*Result), HasSideEffect, false, ReadOnly, ReadNone, InNoMergeAttributedStmt, S, - ResultRegTypes, *this, RegResults); + ResultRegTypes, ArgElemTypes, *this, RegResults); } else if (HasUnwindClobber) { llvm::CallBase *Result = EmitCallOrInvoke(IA, Args, ""); UpdateAsmCallInst(*Result, HasSideEffect, true, ReadOnly, ReadNone, - InNoMergeAttributedStmt, S, ResultRegTypes, *this, - RegResults); + InNoMergeAttributedStmt, S, ResultRegTypes, ArgElemTypes, + *this, RegResults); } else { llvm::CallInst *Result = Builder.CreateCall(IA, Args, getBundlesForFunclet(IA)); UpdateAsmCallInst(cast<llvm::CallBase>(*Result), HasSideEffect, false, ReadOnly, ReadNone, InNoMergeAttributedStmt, S, - ResultRegTypes, *this, RegResults); + ResultRegTypes, ArgElemTypes, *this, RegResults); } assert(RegResults.size() == ResultRegTypes.size()); diff --git contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp index 4c11f7d67534..0db59dd2624c 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -2584,7 +2584,67 @@ static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S, } } +static bool isSupportedByOpenMPIRBuilder(const OMPExecutableDirective &S) { + // Check for unsupported clauses + if (!S.clauses().empty()) { + // Currently no clause is supported + return false; + } + + // Check if we have a statement with the ordered directive. + // Visit the statement hierarchy to find a compound statement + // with a ordered directive in it. + if (const auto *CanonLoop = dyn_cast<OMPCanonicalLoop>(S.getRawStmt())) { + if (const Stmt *SyntacticalLoop = CanonLoop->getLoopStmt()) { + for (const Stmt *SubStmt : SyntacticalLoop->children()) { + if (!SubStmt) + continue; + if (const CompoundStmt *CS = dyn_cast<CompoundStmt>(SubStmt)) { + for (const Stmt *CSSubStmt : CS->children()) { + if (!CSSubStmt) + continue; + if (isa<OMPOrderedDirective>(CSSubStmt)) { + return false; + } + } + } + } + } + } + return true; +} + void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { + bool UseOMPIRBuilder = + CGM.getLangOpts().OpenMPIRBuilder && isSupportedByOpenMPIRBuilder(S); + if (UseOMPIRBuilder) { + auto &&CodeGenIRBuilder = [this, &S, UseOMPIRBuilder](CodeGenFunction &CGF, + PrePostActionTy &) { + // Use the OpenMPIRBuilder if enabled. + if (UseOMPIRBuilder) { + // Emit the associated statement and get its loop representation. + llvm::DebugLoc DL = SourceLocToDebugLoc(S.getBeginLoc()); + const Stmt *Inner = S.getRawStmt(); + llvm::CanonicalLoopInfo *CLI = + EmitOMPCollapsedCanonicalLoopNest(Inner, 1); + + llvm::OpenMPIRBuilder &OMPBuilder = + CGM.getOpenMPRuntime().getOMPBuilder(); + // Add SIMD specific metadata + OMPBuilder.applySimd(DL, CLI); + return; + } + }; + { + auto LPCRegion = + CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); + OMPLexicalScope Scope(*this, S, OMPD_unknown); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, + CodeGenIRBuilder); + } + return; + } + ParentLoopDirectiveForScanRegion ScanRegion(*this, S); OMPFirstScanLoop = true; auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { @@ -4460,8 +4520,9 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( CGF.getContext().getASTRecordLayout(CaptureRecord); unsigned Offset = Layout.getFieldOffset(It->second->getFieldIndex()) / CharWidth; - (void)DI->EmitDeclareOfAutoVariable(SharedVar, ContextValue, - CGF.Builder, false); + if (CGF.CGM.getCodeGenOpts().hasReducedDebugInfo()) + (void)DI->EmitDeclareOfAutoVariable(SharedVar, ContextValue, + CGF.Builder, false); llvm::Instruction &Last = CGF.Builder.GetInsertBlock()->back(); // Get the call dbg.declare instruction we just created and update // its DIExpression to add offset to base address. @@ -4560,8 +4621,10 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( CGF.getContext().getDeclAlign(Pair.first)); Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; }); if (auto *DI = CGF.getDebugInfo()) - DI->EmitDeclareOfAutoVariable(Pair.first, Pair.second.getPointer(), - CGF.Builder, /*UsePointerValue*/ true); + if (CGF.CGM.getCodeGenOpts().hasReducedDebugInfo()) + (void)DI->EmitDeclareOfAutoVariable( + Pair.first, Pair.second.getPointer(), CGF.Builder, + /*UsePointerValue*/ true); } // Adjust mapping for internal locals by mapping actual memory instead of // a pointer to this memory. @@ -6046,6 +6109,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_inbranch: case OMPC_notinbranch: case OMPC_link: + case OMPC_indirect: case OMPC_use: case OMPC_novariants: case OMPC_nocontext: @@ -6789,7 +6853,7 @@ void CodeGenFunction::EmitOMPTargetDataDirective( public: explicit DevicePointerPrivActionTy(bool &PrivatizeDevicePointers) - : PrePostActionTy(), PrivatizeDevicePointers(PrivatizeDevicePointers) {} + : PrivatizeDevicePointers(PrivatizeDevicePointers) {} void Enter(CodeGenFunction &CGF) override { PrivatizeDevicePointers = true; } diff --git contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp index 482499da1b0f..c839376880c4 100644 --- contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp @@ -1178,7 +1178,7 @@ bool CodeGenModule::HasLTOVisibilityPublicStd(const CXXRecordDecl *RD) { return false; const DeclContext *DC = RD; - while (1) { + while (true) { auto *D = cast<Decl>(DC); DC = DC->getParent(); if (isa<TranslationUnitDecl>(DC->getRedeclContext())) { diff --git contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp index e6adec6948af..50e1638924d1 100644 --- contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp @@ -740,7 +740,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, #include "clang/Basic/Sanitizers.def" #undef SANITIZER - } while (0); + } while (false); if (D) { bool NoSanitizeCoverage = false; @@ -882,6 +882,13 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (Offset) Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset)); } + // Instruct that functions for COFF/CodeView targets should start with a + // patchable instruction, but only on x86/x64. Don't forward this to ARM/ARM64 + // backends as they don't need it -- instructions on these architectures are + // always atomically patchable at runtime. + if (CGM.getCodeGenOpts().HotPatch && + getContext().getTargetInfo().getTriple().isX86()) + Fn->addFnAttr("patchable-function", "prologue-short-redirect"); // Add no-jump-tables value. if (CGM.getCodeGenOpts().NoUseJumpTables) @@ -1595,9 +1602,9 @@ void CodeGenFunction::EmitBranchToCounterBlock( if (!InstrumentRegions || !isInstrumentedCondition(Cond)) return EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount, LH); - llvm::BasicBlock *ThenBlock = NULL; - llvm::BasicBlock *ElseBlock = NULL; - llvm::BasicBlock *NextBlock = NULL; + llvm::BasicBlock *ThenBlock = nullptr; + llvm::BasicBlock *ElseBlock = nullptr; + llvm::BasicBlock *NextBlock = nullptr; // Create the block we'll use to increment the appropriate counter. llvm::BasicBlock *CounterIncrBlock = createBasicBlock("lop.rhscnt"); @@ -2109,6 +2116,7 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType, // Create the actual GEP. addr = Address(Builder.CreateInBoundsGEP( addr.getElementType(), addr.getPointer(), gepIndices, "array.begin"), + ConvertTypeForMem(eltType), addr.getAlignment()); } @@ -2246,32 +2254,36 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { // Unknown size indication requires no size computation. // Otherwise, evaluate and record it. - if (const Expr *size = vat->getSizeExpr()) { + if (const Expr *sizeExpr = vat->getSizeExpr()) { // It's possible that we might have emitted this already, // e.g. with a typedef and a pointer to it. - llvm::Value *&entry = VLASizeMap[size]; + llvm::Value *&entry = VLASizeMap[sizeExpr]; if (!entry) { - llvm::Value *Size = EmitScalarExpr(size); + llvm::Value *size = EmitScalarExpr(sizeExpr); // C11 6.7.6.2p5: // If the size is an expression that is not an integer constant // expression [...] each time it is evaluated it shall have a value // greater than zero. - if (SanOpts.has(SanitizerKind::VLABound) && - size->getType()->isSignedIntegerType()) { + if (SanOpts.has(SanitizerKind::VLABound)) { SanitizerScope SanScope(this); - llvm::Value *Zero = llvm::Constant::getNullValue(Size->getType()); + llvm::Value *Zero = llvm::Constant::getNullValue(size->getType()); + clang::QualType SEType = sizeExpr->getType(); + llvm::Value *CheckCondition = + SEType->isSignedIntegerType() + ? Builder.CreateICmpSGT(size, Zero) + : Builder.CreateICmpUGT(size, Zero); llvm::Constant *StaticArgs[] = { - EmitCheckSourceLocation(size->getBeginLoc()), - EmitCheckTypeDescriptor(size->getType())}; - EmitCheck(std::make_pair(Builder.CreateICmpSGT(Size, Zero), - SanitizerKind::VLABound), - SanitizerHandler::VLABoundNotPositive, StaticArgs, Size); + EmitCheckSourceLocation(sizeExpr->getBeginLoc()), + EmitCheckTypeDescriptor(SEType)}; + EmitCheck(std::make_pair(CheckCondition, SanitizerKind::VLABound), + SanitizerHandler::VLABoundNotPositive, StaticArgs, size); } // Always zexting here would be wrong if it weren't // undefined behavior to have a negative bound. - entry = Builder.CreateIntCast(Size, SizeTy, /*signed*/ false); + // FIXME: What about when size's type is larger than size_t? + entry = Builder.CreateIntCast(size, SizeTy, /*signed*/ false); } } type = vat->getElementType(); @@ -2694,7 +2706,7 @@ void CodeGenFunction::emitAlignmentAssumptionCheck( SanitizerScope SanScope(this); if (!OffsetValue) - OffsetValue = Builder.getInt1(0); // no offset. + OffsetValue = Builder.getInt1(false); // no offset. llvm::Constant *StaticData[] = {EmitCheckSourceLocation(Loc), EmitCheckSourceLocation(SecondaryLoc), diff --git contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h index f76ce8a6400d..6db888dcec08 100644 --- contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h +++ contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h @@ -46,7 +46,6 @@ namespace llvm { class BasicBlock; class LLVMContext; class MDNode; -class Module; class SwitchInst; class Twine; class Value; @@ -55,13 +54,11 @@ class CanonicalLoopInfo; namespace clang { class ASTContext; -class BlockDecl; class CXXDestructorDecl; class CXXForRangeStmt; class CXXTryStmt; class Decl; class LabelDecl; -class EnumConstantDecl; class FunctionDecl; class FunctionProtoType; class LabelStmt; @@ -80,7 +77,6 @@ class ObjCAtSynchronizedStmt; class ObjCAutoreleasePoolStmt; class OMPUseDevicePtrClause; class OMPUseDeviceAddrClause; -class ReturnsNonNullAttr; class SVETypeFlags; class OMPExecutableDirective; @@ -92,12 +88,10 @@ namespace CodeGen { class CodeGenTypes; class CGCallee; class CGFunctionInfo; -class CGRecordLayout; class CGBlockInfo; class CGCXXABI; class BlockByrefHelpers; class BlockByrefInfo; -class BlockFlags; class BlockFieldFlags; class RegionCodeGenTy; class TargetCodeGenInfo; @@ -182,6 +176,7 @@ template <> struct DominatingValue<Address> { struct saved_type { DominatingLLVMValue::saved_type SavedValue; + llvm::Type *ElementType; CharUnits Alignment; }; @@ -190,11 +185,11 @@ template <> struct DominatingValue<Address> { } static saved_type save(CodeGenFunction &CGF, type value) { return { DominatingLLVMValue::save(CGF, value.getPointer()), - value.getAlignment() }; + value.getElementType(), value.getAlignment() }; } static type restore(CodeGenFunction &CGF, saved_type value) { return Address(DominatingLLVMValue::restore(CGF, value.SavedValue), - value.Alignment); + value.ElementType, value.Alignment); } }; @@ -241,11 +236,10 @@ public: /// A jump destination is an abstract label, branching to which may /// require a jump out through normal cleanups. struct JumpDest { - JumpDest() : Block(nullptr), ScopeDepth(), Index(0) {} - JumpDest(llvm::BasicBlock *Block, - EHScopeStack::stable_iterator Depth, + JumpDest() : Block(nullptr), Index(0) {} + JumpDest(llvm::BasicBlock *Block, EHScopeStack::stable_iterator Depth, unsigned Index) - : Block(Block), ScopeDepth(Depth), Index(Index) {} + : Block(Block), ScopeDepth(Depth), Index(Index) {} bool isValid() const { return Block != nullptr; } llvm::BasicBlock *getBlock() const { return Block; } @@ -4677,13 +4671,14 @@ private: SmallVectorImpl<llvm::Value *> &IRCallArgs, unsigned &IRCallArgPos); - llvm::Value* EmitAsmInput(const TargetInfo::ConstraintInfo &Info, - const Expr *InputExpr, std::string &ConstraintStr); + std::pair<llvm::Value *, llvm::Type *> + EmitAsmInput(const TargetInfo::ConstraintInfo &Info, const Expr *InputExpr, + std::string &ConstraintStr); - llvm::Value* EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, - LValue InputValue, QualType InputType, - std::string &ConstraintStr, - SourceLocation Loc); + std::pair<llvm::Value *, llvm::Type *> + EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, LValue InputValue, + QualType InputType, std::string &ConstraintStr, + SourceLocation Loc); /// Attempts to statically evaluate the object size of E. If that /// fails, emits code to figure the size of E out for us. This is diff --git contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp index 36b7ce87336c..d534cf182f5a 100644 --- contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp @@ -565,7 +565,9 @@ void CodeGenModule::Release() { "__amdgpu_device_library_preserve_asan_functions_ptr", nullptr, llvm::GlobalVariable::NotThreadLocal); addCompilerUsedGlobal(Var); - getModule().addModuleFlag(llvm::Module::Override, "amdgpu_hostcall", 1); + if (!getModule().getModuleFlag("amdgpu_hostcall")) { + getModule().addModuleFlag(llvm::Module::Override, "amdgpu_hostcall", 1); + } } emitLLVMUsed(); @@ -610,7 +612,7 @@ void CodeGenModule::Release() { if (Context.getLangOpts().SemanticInterposition) // Require various optimization to respect semantic interposition. - getModule().setSemanticInterposition(1); + getModule().setSemanticInterposition(true); if (CodeGenOpts.EmitCodeView) { // Indicate that we want CodeView in the metadata. @@ -710,6 +712,9 @@ void CodeGenModule::Release() { 1); } + if (CodeGenOpts.IBTSeal) + getModule().addModuleFlag(llvm::Module::Override, "ibt-seal", 1); + // Add module metadata for return address signing (ignoring // non-leaf/all) and stack tagging. These are actually turned on by function // attributes, but we use module metadata to emit build attributes. This is @@ -1368,7 +1373,8 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD, } void CodeGenModule::UpdateMultiVersionNames(GlobalDecl GD, - const FunctionDecl *FD) { + const FunctionDecl *FD, + StringRef &CurName) { if (!FD->isMultiVersion()) return; @@ -1400,7 +1406,11 @@ void CodeGenModule::UpdateMultiVersionNames(GlobalDecl GD, if (ExistingRecord != std::end(Manglings)) Manglings.remove(&(*ExistingRecord)); auto Result = Manglings.insert(std::make_pair(OtherName, OtherGD)); - MangledDeclNames[OtherGD.getCanonicalDecl()] = Result.first->first(); + StringRef OtherNameRef = MangledDeclNames[OtherGD.getCanonicalDecl()] = + Result.first->first(); + // If this is the current decl is being created, make sure we update the name. + if (GD.getCanonicalDecl() == OtherGD.getCanonicalDecl()) + CurName = OtherNameRef; if (llvm::GlobalValue *Entry = GetGlobalValue(NonTargetName)) Entry->setName(OtherName); } @@ -1819,7 +1829,7 @@ CodeGenModule::getMostBaseClasses(const CXXRecordDecl *RD) { void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F) { - llvm::AttrBuilder B; + llvm::AttrBuilder B(F->getContext()); if (CodeGenOpts.UnwindTables) B.addAttribute(llvm::Attribute::UWTable); @@ -1982,7 +1992,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, void CodeGenModule::setLLVMFunctionFEnvAttributes(const FunctionDecl *D, llvm::Function *F) { if (D->hasAttr<StrictFPAttr>()) { - llvm::AttrBuilder FuncAttrs; + llvm::AttrBuilder FuncAttrs(F->getContext()); FuncAttrs.addAttribute("strictfp"); F->addFnAttrs(FuncAttrs); } @@ -2092,12 +2102,12 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD, if (!D->getAttr<SectionAttr>()) F->addFnAttr("implicit-section-name", SA->getName()); - llvm::AttrBuilder Attrs; + llvm::AttrBuilder Attrs(F->getContext()); if (GetCPUAndFeaturesAttributes(GD, Attrs)) { // We know that GetCPUAndFeaturesAttributes will always have the // newest set, since it has the newest possible FunctionDecl, so the // new ones should replace the old. - llvm::AttrBuilder RemoveAttrs; + llvm::AttributeMask RemoveAttrs; RemoveAttrs.addAttribute("target-cpu"); RemoveAttrs.addAttribute("target-features"); RemoveAttrs.addAttribute("tune-cpu"); @@ -3479,6 +3489,7 @@ void CodeGenModule::emitMultiVersionFunctions() { void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { const auto *FD = cast<FunctionDecl>(GD.getDecl()); assert(FD && "Not a FunctionDecl?"); + assert(FD->isCPUDispatchMultiVersion() && "Not a multiversion function?"); const auto *DD = FD->getAttr<CPUDispatchAttr>(); assert(DD && "Not a cpu_dispatch Function?"); llvm::Type *DeclTy = getTypes().ConvertType(FD->getType()); @@ -3489,14 +3500,16 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { } StringRef ResolverName = getMangledName(GD); + UpdateMultiVersionNames(GD, FD, ResolverName); llvm::Type *ResolverType; GlobalDecl ResolverGD; - if (getTarget().supportsIFunc()) + if (getTarget().supportsIFunc()) { ResolverType = llvm::FunctionType::get( llvm::PointerType::get(DeclTy, Context.getTargetAddressSpace(FD->getType())), false); + } else { ResolverType = DeclTy; ResolverGD = GD; @@ -3688,8 +3701,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( } if (FD->isMultiVersion()) { - if (FD->hasAttr<TargetAttr>()) - UpdateMultiVersionNames(GD, FD); + UpdateMultiVersionNames(GD, FD, MangledName); if (!IsForDefinition) return GetOrCreateMultiVersionResolver(GD, Ty, FD); } @@ -3785,7 +3797,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( if (D) SetFunctionAttributes(GD, F, IsIncompleteFunction, IsThunk); if (ExtraAttrs.hasFnAttrs()) { - llvm::AttrBuilder B(ExtraAttrs, llvm::AttributeList::FunctionIndex); + llvm::AttrBuilder B(F->getContext(), ExtraAttrs.getFnAttrs()); F->addFnAttrs(B); } diff --git contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h index f1565511f98a..e803022508a4 100644 --- contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h +++ contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h @@ -46,7 +46,6 @@ class GlobalValue; class DataLayout; class FunctionType; class LLVMContext; -class OpenMPIRBuilder; class IndexedInstrProfReader; } @@ -55,17 +54,13 @@ class ASTContext; class AtomicType; class FunctionDecl; class IdentifierInfo; -class ObjCMethodDecl; class ObjCImplementationDecl; -class ObjCCategoryImplDecl; -class ObjCProtocolDecl; class ObjCEncodeExpr; class BlockExpr; class CharUnits; class Decl; class Expr; class Stmt; -class InitListExpr; class StringLiteral; class NamedDecl; class ValueDecl; @@ -78,13 +73,10 @@ class AnnotateAttr; class CXXDestructorDecl; class Module; class CoverageSourceInfo; -class TargetAttr; class InitSegAttr; -struct ParsedTargetAttr; namespace CodeGen { -class CallArgList; class CodeGenFunction; class CodeGenTBAA; class CGCXXABI; @@ -93,8 +85,6 @@ class CGObjCRuntime; class CGOpenCLRuntime; class CGOpenMPRuntime; class CGCUDARuntime; -class BlockFieldFlags; -class FunctionArgList; class CoverageMappingModuleGen; class TargetCodeGenInfo; @@ -311,7 +301,7 @@ private: const TargetInfo &Target; std::unique_ptr<CGCXXABI> ABI; llvm::LLVMContext &VMContext; - std::string ModuleNameHash = ""; + std::string ModuleNameHash; std::unique_ptr<CodeGenTBAA> TBAA; @@ -345,7 +335,7 @@ private: /// for emission and therefore should only be output if they are actually /// used. If a decl is in this, then it is known to have not been referenced /// yet. - std::map<StringRef, GlobalDecl> DeferredDecls; + llvm::DenseMap<StringRef, GlobalDecl> DeferredDecls; /// This is a list of deferred decls which we have seen that *are* actually /// referenced. These get code generated when the module is done. @@ -1478,7 +1468,8 @@ private: llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD, llvm::Type *DeclTy, const FunctionDecl *FD); - void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD); + void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD, + StringRef &CurName); llvm::Constant * GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, LangAS AddrSpace, diff --git contrib/llvm-project/clang/lib/CodeGen/CodeGenPGO.cpp contrib/llvm-project/clang/lib/CodeGen/CodeGenPGO.cpp index ab953c2c7d52..6657f2a91e3d 100644 --- contrib/llvm-project/clang/lib/CodeGen/CodeGenPGO.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CodeGenPGO.cpp @@ -131,7 +131,7 @@ public: static_assert(LastHashType <= TooBig, "Too many types in HashType"); PGOHash(PGOHashVersion HashVersion) - : Working(0), Count(0), HashVersion(HashVersion), MD5() {} + : Working(0), Count(0), HashVersion(HashVersion) {} void combine(HashType Type); uint64_t finalize(); PGOHashVersion getHashVersion() const { return HashVersion; } diff --git contrib/llvm-project/clang/lib/CodeGen/CodeGenTBAA.h contrib/llvm-project/clang/lib/CodeGen/CodeGenTBAA.h index e8e006f41616..a65963596fe9 100644 --- contrib/llvm-project/clang/lib/CodeGen/CodeGenTBAA.h +++ contrib/llvm-project/clang/lib/CodeGen/CodeGenTBAA.h @@ -29,7 +29,6 @@ namespace clang { class Type; namespace CodeGen { -class CGRecordLayout; // TBAAAccessKind - A kind of TBAA memory access descriptor. enum class TBAAAccessKind : unsigned { diff --git contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.cpp contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.cpp index 77721510dfd0..4839e22c4b14 100644 --- contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.cpp +++ contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.cpp @@ -643,11 +643,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { llvm::Type *PointeeType = ConvertTypeForMem(ETy); if (PointeeType->isVoidTy()) PointeeType = llvm::Type::getInt8Ty(getLLVMContext()); - - unsigned AS = PointeeType->isFunctionTy() - ? getDataLayout().getProgramAddressSpace() - : Context.getTargetAddressSpace(ETy); - + unsigned AS = Context.getTargetAddressSpace(ETy); ResultType = llvm::PointerType::get(PointeeType, AS); break; } @@ -748,7 +744,13 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { llvm::Type *PointeeType = CGM.getLangOpts().OpenCL ? CGM.getGenericBlockLiteralType() : ConvertTypeForMem(FTy); - unsigned AS = Context.getTargetAddressSpace(FTy); + // Block pointers lower to function type. For function type, + // getTargetAddressSpace() returns default address space for + // function pointer i.e. program address space. Therefore, for block + // pointers, it is important to pass qualifiers when calling + // getTargetAddressSpace(), to ensure that we get the address space + // for data pointers and not function pointers. + unsigned AS = Context.getTargetAddressSpace(FTy.getQualifiers()); ResultType = llvm::PointerType::get(PointeeType, AS); break; } diff --git contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h index f8f7542e4c83..28b831222943 100644 --- contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h +++ contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h @@ -31,14 +31,9 @@ namespace clang { class ASTContext; template <typename> class CanQual; class CXXConstructorDecl; -class CXXDestructorDecl; class CXXMethodDecl; class CodeGenOptions; -class FieldDecl; class FunctionProtoType; -class ObjCInterfaceDecl; -class ObjCIvarDecl; -class PointerType; class QualType; class RecordDecl; class TagDecl; diff --git contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp index 1a15b09c7b2b..2979d92c8417 100644 --- contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -334,59 +334,6 @@ public: ArrayRef<llvm::Function *> CXXThreadLocalInits, ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override; - bool mayNeedDestruction(const VarDecl *VD) const { - if (VD->needsDestruction(getContext())) - return true; - - // If the variable has an incomplete class type (or array thereof), it - // might need destruction. - const Type *T = VD->getType()->getBaseElementTypeUnsafe(); - if (T->getAs<RecordType>() && T->isIncompleteType()) - return true; - - return false; - } - - /// Determine whether we will definitely emit this variable with a constant - /// initializer, either because the language semantics demand it or because - /// we know that the initializer is a constant. - // For weak definitions, any initializer available in the current translation - // is not necessarily reflective of the initializer used; such initializers - // are ignored unless if InspectInitForWeakDef is true. - bool - isEmittedWithConstantInitializer(const VarDecl *VD, - bool InspectInitForWeakDef = false) const { - VD = VD->getMostRecentDecl(); - if (VD->hasAttr<ConstInitAttr>()) - return true; - - // All later checks examine the initializer specified on the variable. If - // the variable is weak, such examination would not be correct. - if (!InspectInitForWeakDef && - (VD->isWeak() || VD->hasAttr<SelectAnyAttr>())) - return false; - - const VarDecl *InitDecl = VD->getInitializingDeclaration(); - if (!InitDecl) - return false; - - // If there's no initializer to run, this is constant initialization. - if (!InitDecl->hasInit()) - return true; - - // If we have the only definition, we don't need a thread wrapper if we - // will emit the value as a constant. - if (isUniqueGVALinkage(getContext().GetGVALinkageForVariable(VD))) - return !mayNeedDestruction(VD) && InitDecl->evaluateValue(); - - // Otherwise, we need a thread wrapper unless we know that every - // translation unit will emit the value as a constant. We rely on the - // variable being constant-initialized in every translation unit if it's - // constant-initialized in any translation unit, which isn't actually - // guaranteed by the standard but is necessary for sanity. - return InitDecl->hasConstantInitialization(); - } - bool usesThreadWrapperFunction(const VarDecl *VD) const override { return !isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD); @@ -697,8 +644,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( CharUnits VTablePtrAlign = CGF.CGM.getDynamicOffsetAlignment(ThisAddr.getAlignment(), RD, CGF.getPointerAlign()); - llvm::Value *VTable = - CGF.GetVTablePtr(Address(This, VTablePtrAlign), VTableTy, RD); + llvm::Value *VTable = CGF.GetVTablePtr( + Address(This, ThisAddr.getElementType(), VTablePtrAlign), VTableTy, RD); // Apply the offset. // On ARM64, to reserve extra space in virtual member function pointers, @@ -4525,8 +4472,7 @@ static void InitCatchParam(CodeGenFunction &CGF, // pad. The best solution is to fix the personality function. } else { // Pull the pointer for the reference type off. - llvm::Type *PtrTy = - cast<llvm::PointerType>(LLVMCatchTy)->getElementType(); + llvm::Type *PtrTy = LLVMCatchTy->getPointerElementType(); // Create the temporary and write the adjusted pointer into it. Address ExnPtrTmp = diff --git contrib/llvm-project/clang/lib/CodeGen/MacroPPCallbacks.h contrib/llvm-project/clang/lib/CodeGen/MacroPPCallbacks.h index 32906a000269..d249b5b0eb88 100644 --- contrib/llvm-project/clang/lib/CodeGen/MacroPPCallbacks.h +++ contrib/llvm-project/clang/lib/CodeGen/MacroPPCallbacks.h @@ -17,7 +17,6 @@ namespace llvm { class DIMacroFile; -class DIMacroNode; } namespace clang { class Preprocessor; diff --git contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 5971a7709304..e00ff2b68719 100644 --- contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -401,7 +401,9 @@ public: ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override; bool usesThreadWrapperFunction(const VarDecl *VD) const override { - return false; + return getContext().getLangOpts().isCompatibleWithMSVC( + LangOptions::MSVC2019_5) && + (!isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD)); } LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType) override; @@ -2397,11 +2399,97 @@ void MicrosoftCXXABI::EmitThreadLocalInitFuncs( } } +static llvm::GlobalValue *getTlsGuardVar(CodeGenModule &CGM) { + // __tls_guard comes from the MSVC runtime and reflects + // whether TLS has been initialized for a particular thread. + // It is set from within __dyn_tls_init by the runtime. + // Every library and executable has its own variable. + llvm::Type *VTy = llvm::Type::getInt8Ty(CGM.getLLVMContext()); + llvm::Constant *TlsGuardConstant = + CGM.CreateRuntimeVariable(VTy, "__tls_guard"); + llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(TlsGuardConstant); + + TlsGuard->setThreadLocal(true); + + return TlsGuard; +} + +static llvm::FunctionCallee getDynTlsOnDemandInitFn(CodeGenModule &CGM) { + // __dyn_tls_on_demand_init comes from the MSVC runtime and triggers + // dynamic TLS initialization by calling __dyn_tls_init internally. + llvm::FunctionType *FTy = + llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()), {}, + /*isVarArg=*/false); + return CGM.CreateRuntimeFunction( + FTy, "__dyn_tls_on_demand_init", + llvm::AttributeList::get(CGM.getLLVMContext(), + llvm::AttributeList::FunctionIndex, + llvm::Attribute::NoUnwind), + /*Local=*/true); +} + +static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, + llvm::BasicBlock *DynInitBB, + llvm::BasicBlock *ContinueBB) { + llvm::LoadInst *TlsGuardValue = + CGF.Builder.CreateLoad(Address(TlsGuard, CharUnits::One())); + llvm::Value *CmpResult = + CGF.Builder.CreateICmpEQ(TlsGuardValue, CGF.Builder.getInt8(0)); + CGF.Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB); +} + +static void emitDynamicTlsInitializationCall(CodeGenFunction &CGF, + llvm::GlobalValue *TlsGuard, + llvm::BasicBlock *ContinueBB) { + llvm::FunctionCallee Initializer = getDynTlsOnDemandInitFn(CGF.CGM); + llvm::Function *InitializerFunction = + cast<llvm::Function>(Initializer.getCallee()); + llvm::CallInst *CallVal = CGF.Builder.CreateCall(InitializerFunction); + CallVal->setCallingConv(InitializerFunction->getCallingConv()); + + CGF.Builder.CreateBr(ContinueBB); +} + +static void emitDynamicTlsInitialization(CodeGenFunction &CGF) { + llvm::BasicBlock *DynInitBB = + CGF.createBasicBlock("dyntls.dyn_init", CGF.CurFn); + llvm::BasicBlock *ContinueBB = + CGF.createBasicBlock("dyntls.continue", CGF.CurFn); + + llvm::GlobalValue *TlsGuard = getTlsGuardVar(CGF.CGM); + + emitTlsGuardCheck(CGF, TlsGuard, DynInitBB, ContinueBB); + CGF.Builder.SetInsertPoint(DynInitBB); + emitDynamicTlsInitializationCall(CGF, TlsGuard, ContinueBB); + CGF.Builder.SetInsertPoint(ContinueBB); +} + LValue MicrosoftCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType) { - CGF.CGM.ErrorUnsupported(VD, "thread wrappers"); - return LValue(); + // Dynamic TLS initialization works by checking the state of a + // guard variable (__tls_guard) to see whether TLS initialization + // for a thread has happend yet. + // If not, the initialization is triggered on-demand + // by calling __dyn_tls_on_demand_init. + emitDynamicTlsInitialization(CGF); + + // Emit the variable just like any regular global variable. + + llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD); + llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(VD->getType()); + + unsigned AS = cast<llvm::PointerType>(V->getType())->getAddressSpace(); + V = CGF.Builder.CreateBitCast(V, RealVarTy->getPointerTo(AS)); + + CharUnits Alignment = CGF.getContext().getDeclAlign(VD); + Address Addr(V, Alignment); + + LValue LV = VD->getType()->isReferenceType() + ? CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(), + AlignmentSource::Decl) + : CGF.MakeAddrLValue(Addr, LValType, AlignmentSource::Decl); + return LV; } static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM) { diff --git contrib/llvm-project/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp contrib/llvm-project/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp index f7b83c45022d..9fe7e5d1f5c3 100644 --- contrib/llvm-project/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp +++ contrib/llvm-project/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp @@ -156,6 +156,7 @@ public: CodeGenOpts.setDebuggerTuning(CI.getCodeGenOpts().getDebuggerTuning()); CodeGenOpts.DebugPrefixMap = CI.getInvocation().getCodeGenOpts().DebugPrefixMap; + CodeGenOpts.DebugStrictDwarf = CI.getCodeGenOpts().DebugStrictDwarf; } ~PCHContainerGenerator() override = default; diff --git contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp index 85089cdb2200..fb81169003fc 100644 --- contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp +++ contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp @@ -855,19 +855,19 @@ public: if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) { if (const auto *Attr = FD->getAttr<WebAssemblyImportModuleAttr>()) { llvm::Function *Fn = cast<llvm::Function>(GV); - llvm::AttrBuilder B; + llvm::AttrBuilder B(GV->getContext()); B.addAttribute("wasm-import-module", Attr->getImportModule()); Fn->addFnAttrs(B); } if (const auto *Attr = FD->getAttr<WebAssemblyImportNameAttr>()) { llvm::Function *Fn = cast<llvm::Function>(GV); - llvm::AttrBuilder B; + llvm::AttrBuilder B(GV->getContext()); B.addAttribute("wasm-import-name", Attr->getImportName()); Fn->addFnAttrs(B); } if (const auto *Attr = FD->getAttr<WebAssemblyExportNameAttr>()) { llvm::Function *Fn = cast<llvm::Function>(GV); - llvm::AttrBuilder B; + llvm::AttrBuilder B(GV->getContext()); B.addAttribute("wasm-export-name", Attr->getExportName()); Fn->addFnAttrs(B); } @@ -1606,7 +1606,7 @@ static bool isSIMDVectorType(ASTContext &Context, QualType Ty) { static bool isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty) { const RecordType *RT = Ty->getAs<RecordType>(); if (!RT) - return 0; + return false; const RecordDecl *RD = RT->getDecl(); // If this is a C++ record, check the bases first. @@ -6414,7 +6414,7 @@ public: // AAPCS guarantees that sp will be 8-byte aligned on any public interface, // however this is not necessarily true on taking any interrupt. Instruct // the backend to perform a realignment as part of the function prologue. - llvm::AttrBuilder B; + llvm::AttrBuilder B(Fn->getContext()); B.addStackAlignmentAttr(8); Fn->addFnAttrs(B); } @@ -8282,14 +8282,15 @@ public: LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const override { - // Check if a global/static variable is defined within address space 1 + // Check if global/static variable is defined in address space + // 1~6 (__flash, __flash1, __flash2, __flash3, __flash4, __flash5) // but not constant. LangAS AS = D->getType().getAddressSpace(); - if (isTargetAddressSpace(AS) && toTargetAddressSpace(AS) == 1 && - !D->getType().isConstQualified()) + if (isTargetAddressSpace(AS) && 1 <= toTargetAddressSpace(AS) && + toTargetAddressSpace(AS) <= 6 && !D->getType().isConstQualified()) CGM.getDiags().Report(D->getLocation(), diag::err_verify_nonconst_addrspace) - << "__flash"; + << "__flash*"; return TargetCodeGenInfo::getGlobalVarAddressSpace(CGM, D); } @@ -8693,7 +8694,7 @@ Address HexagonABIInfo::EmitVAArgForHexagonLinux(CodeGenFunction &CGF, llvm::ConstantInt::get(CGF.Int32Ty, ArgSize), "__new_saved_reg_area_pointer"); - llvm::Value *UsingStack = 0; + llvm::Value *UsingStack = nullptr; UsingStack = CGF.Builder.CreateICmpSGT(__new_saved_reg_area_pointer, __saved_reg_area_end_pointer); @@ -8935,9 +8936,9 @@ private: llvm::Type *coerceKernelArgumentType(llvm::Type *Ty, unsigned FromAS, unsigned ToAS) const { // Single value types. - if (Ty->isPointerTy() && Ty->getPointerAddressSpace() == FromAS) - return llvm::PointerType::get( - cast<llvm::PointerType>(Ty)->getElementType(), ToAS); + auto *PtrTy = llvm::dyn_cast<llvm::PointerType>(Ty); + if (PtrTy && PtrTy->getAddressSpace() == FromAS) + return llvm::PointerType::getWithSamePointeeType(PtrTy, ToAS); return Ty; } @@ -9304,16 +9305,9 @@ void AMDGPUTargetCodeGenInfo::setTargetAttributes( if (FD) setFunctionDeclAttributes(FD, F, M); - const bool IsOpenCLKernel = - M.getLangOpts().OpenCL && FD && FD->hasAttr<OpenCLKernelAttr>(); const bool IsHIPKernel = M.getLangOpts().HIP && FD && FD->hasAttr<CUDAGlobalAttr>(); - const bool IsOpenMP = M.getLangOpts().OpenMP && !FD; - if ((IsOpenCLKernel || IsHIPKernel || IsOpenMP) && - (M.getTriple().getOS() == llvm::Triple::AMDHSA)) - F->addFnAttr("amdgpu-implicitarg-num-bytes", "56"); - if (IsHIPKernel) F->addFnAttr("uniform-work-group-size", "true"); @@ -9340,8 +9334,8 @@ llvm::Constant *AMDGPUTargetCodeGenInfo::getNullPointer( return llvm::ConstantPointerNull::get(PT); auto &Ctx = CGM.getContext(); - auto NPT = llvm::PointerType::get(PT->getElementType(), - Ctx.getTargetAddressSpace(LangAS::opencl_generic)); + auto NPT = llvm::PointerType::getWithSamePointeeType( + PT, Ctx.getTargetAddressSpace(LangAS::opencl_generic)); return llvm::ConstantExpr::getAddrSpaceCast( llvm::ConstantPointerNull::get(NPT), PT); } @@ -10276,9 +10270,9 @@ ABIArgInfo SPIRVABIInfo::classifyKernelArgumentType(QualType Ty) const { llvm::Type *LTy = CGT.ConvertType(Ty); auto DefaultAS = getContext().getTargetAddressSpace(LangAS::Default); auto GlobalAS = getContext().getTargetAddressSpace(LangAS::cuda_device); - if (LTy->isPointerTy() && LTy->getPointerAddressSpace() == DefaultAS) { - LTy = llvm::PointerType::get( - cast<llvm::PointerType>(LTy)->getElementType(), GlobalAS); + auto *PtrTy = llvm::dyn_cast<llvm::PointerType>(LTy); + if (PtrTy && PtrTy->getAddressSpace() == DefaultAS) { + LTy = llvm::PointerType::getWithSamePointeeType(PtrTy, GlobalAS); return ABIArgInfo::getDirect(LTy, 0, nullptr, false); } } @@ -11417,7 +11411,7 @@ TargetCodeGenInfo::createEnqueuedBlockKernel(CodeGenFunction &CGF, auto &C = CGF.getLLVMContext(); std::string Name = Invoke->getName().str() + "_kernel"; auto *FT = llvm::FunctionType::get(llvm::Type::getVoidTy(C), ArgTys, false); - auto *F = llvm::Function::Create(FT, llvm::GlobalValue::InternalLinkage, Name, + auto *F = llvm::Function::Create(FT, llvm::GlobalValue::ExternalLinkage, Name, &CGF.CGM.getModule()); auto IP = CGF.Builder.saveIP(); auto *BB = llvm::BasicBlock::Create(C, "entry", F); diff --git contrib/llvm-project/clang/lib/CodeGen/TargetInfo.h contrib/llvm-project/clang/lib/CodeGen/TargetInfo.h index aa8bbb60a75f..dfdb2f5f55bb 100644 --- contrib/llvm-project/clang/lib/CodeGen/TargetInfo.h +++ contrib/llvm-project/clang/lib/CodeGen/TargetInfo.h @@ -38,7 +38,6 @@ class ABIInfo; class CallArgList; class CodeGenFunction; class CGBlockInfo; -class CGFunctionInfo; /// TargetCodeGenInfo - This class organizes various target-specific /// codegeneration issues, like target-specific attributes, builtins and so diff --git contrib/llvm-project/clang/lib/Driver/Driver.cpp contrib/llvm-project/clang/lib/Driver/Driver.cpp index 3b551ea94cc2..2e4ebc10e9ba 100644 --- contrib/llvm-project/clang/lib/Driver/Driver.cpp +++ contrib/llvm-project/clang/lib/Driver/Driver.cpp @@ -62,6 +62,7 @@ #include "clang/Driver/SanitizerArgs.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" +#include "clang/Driver/Types.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" @@ -170,13 +171,11 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, : Diags(Diags), VFS(std::move(VFS)), Mode(GCCMode), SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None), ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT), - DriverTitle(Title), CCPrintStatReportFilename(), CCPrintOptionsFilename(), - CCPrintHeadersFilename(), CCLogDiagnosticsFilename(), - CCCPrintBindings(false), CCPrintOptions(false), CCPrintHeaders(false), - CCLogDiagnostics(false), CCGenDiagnostics(false), - CCPrintProcessStats(false), TargetTriple(TargetTriple), - CCCGenericGCCName(""), Saver(Alloc), CheckInputsExist(true), - GenReproducer(false), SuppressMissingInputWarning(false) { + DriverTitle(Title), CCCPrintBindings(false), CCPrintOptions(false), + CCPrintHeaders(false), CCLogDiagnostics(false), CCGenDiagnostics(false), + CCPrintProcessStats(false), TargetTriple(TargetTriple), Saver(Alloc), + CheckInputsExist(true), GenReproducer(false), + SuppressMissingInputWarning(false) { // Provide a sane fallback if no VFS is specified. if (!this->VFS) this->VFS = llvm::vfs::getRealFileSystem(); @@ -328,7 +327,8 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) || (PhaseArg = DAL.getLastArg(options::OPT__migrate)) || (PhaseArg = DAL.getLastArg(options::OPT__analyze)) || - (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) { + (PhaseArg = DAL.getLastArg(options::OPT_emit_ast)) || + (PhaseArg = DAL.getLastArg(options::OPT_extract_api))) { FinalPhase = phases::Compile; // -S only runs up to the backend. @@ -369,7 +369,20 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { bool HasNostdlib = Args.hasArg(options::OPT_nostdlib); bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx); bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs); + bool IgnoreUnused = false; for (Arg *A : Args) { + if (IgnoreUnused) + A->claim(); + + if (A->getOption().matches(options::OPT_start_no_unused_arguments)) { + IgnoreUnused = true; + continue; + } + if (A->getOption().matches(options::OPT_end_no_unused_arguments)) { + IgnoreUnused = false; + continue; + } + // Unfortunately, we have to parse some forwarding options (-Xassembler, // -Xlinker, -Xpreprocessor) because we either integrate their functionality // (assembler and preprocessor), or bypass a previous driver ('collect2'). @@ -437,7 +450,7 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { // Enforce -static if -miamcu is present. if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) - DAL->AddFlagArg(0, Opts.getOption(options::OPT_static)); + DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_static)); // Add a default value of -mlinker-version=, if one was given and the user // didn't specify one. @@ -763,6 +776,18 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, llvm::Triple TT(Val); std::string NormalizedName = TT.normalize(); + // We want to expand the shortened versions of the triples passed in to + // the values used for the bitcode libraries for convenience. + if (TT.getVendor() == llvm::Triple::UnknownVendor || + TT.getOS() == llvm::Triple::UnknownOS) { + if (TT.getArch() == llvm::Triple::nvptx) + TT = llvm::Triple("nvptx-nvidia-cuda"); + else if (TT.getArch() == llvm::Triple::nvptx64) + TT = llvm::Triple("nvptx64-nvidia-cuda"); + else if (TT.getArch() == llvm::Triple::amdgcn) + TT = llvm::Triple("amdgcn-amd-amdhsa"); + } + // Make sure we don't have a duplicate triple. auto Duplicate = FoundNormalizedTriples.find(NormalizedName); if (Duplicate != FoundNormalizedTriples.end()) { @@ -1871,9 +1896,16 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { } if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) { - std::string CandidateRuntimePath = TC.getRuntimePath(); - if (getVFS().exists(CandidateRuntimePath)) - llvm::outs() << CandidateRuntimePath << '\n'; + std::string RuntimePath; + // Get the first existing path, if any. + for (auto Path : TC.getRuntimePaths()) { + if (getVFS().exists(Path)) { + RuntimePath = Path; + break; + } + } + if (!RuntimePath.empty()) + llvm::outs() << RuntimePath << '\n'; else llvm::outs() << TC.getCompilerRTPath() << '\n'; return false; @@ -3105,7 +3137,7 @@ class OffloadingActionBuilder final { // We will pass the device action as a host dependence, so we don't // need to do anything else with them. CudaDeviceActions.clear(); - return ABRT_Success; + return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success; } // By default, we produce an action for each device arch. @@ -3138,6 +3170,7 @@ class OffloadingActionBuilder final { assert(DeviceLinkerInputs.size() == GpuArchList.size() && "Linker inputs and GPU arch list sizes do not match."); + ActionList Actions; // Append a new link action for each device. unsigned I = 0; for (auto &LI : DeviceLinkerInputs) { @@ -3149,22 +3182,29 @@ class OffloadingActionBuilder final { OffloadAction::DeviceDependences DeviceLinkDeps; DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0], GpuArchList[I], AssociatedOffloadKind); - AL.push_back(C.MakeAction<OffloadAction>(DeviceLinkDeps, - DeviceLinkAction->getType())); + Actions.push_back(C.MakeAction<OffloadAction>( + DeviceLinkDeps, DeviceLinkAction->getType())); ++I; } DeviceLinkerInputs.clear(); // Create a host object from all the device images by embedding them - // in a fat binary. + // in a fat binary for mixed host-device compilation. For device-only + // compilation, creates a fat binary. OffloadAction::DeviceDependences DDeps; - auto *TopDeviceLinkAction = - C.MakeAction<LinkJobAction>(AL, types::TY_Object); - DDeps.add(*TopDeviceLinkAction, *ToolChains[0], - nullptr, AssociatedOffloadKind); - - // Offload the host object to the host linker. - AL.push_back(C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType())); + if (!CompileDeviceOnly || !BundleOutput.hasValue() || + BundleOutput.getValue()) { + auto *TopDeviceLinkAction = C.MakeAction<LinkJobAction>( + Actions, + CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object); + DDeps.add(*TopDeviceLinkAction, *ToolChains[0], nullptr, + AssociatedOffloadKind); + // Offload the host object to the host linker. + AL.push_back( + C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType())); + } else { + AL.append(Actions); + } } Action* appendLinkHostActions(ActionList &AL) override { return AL.back(); } @@ -3551,15 +3591,18 @@ public: return false; } - Action* makeHostLinkAction() { - // Build a list of device linking actions. - ActionList DeviceAL; + void appendDeviceLinkActions(ActionList &AL) { for (DeviceActionBuilder *SB : SpecializedBuilders) { if (!SB->isValid()) continue; - SB->appendLinkDeviceActions(DeviceAL); + SB->appendLinkDeviceActions(AL); } + } + Action *makeHostLinkAction() { + // Build a list of device linking actions. + ActionList DeviceAL; + appendDeviceLinkActions(DeviceAL); if (DeviceAL.empty()) return nullptr; @@ -3775,14 +3818,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, } } - // FIXME: Linking separate translation units for SPIR-V is not supported yet. - // It can be done either by LLVM IR linking before conversion of the final - // linked module to SPIR-V or external SPIR-V linkers can be used e.g. - // spirv-link. - if (C.getDefaultToolChain().getTriple().isSPIRV() && Inputs.size() > 1) { - Diag(clang::diag::warn_drv_spirv_linking_multiple_inputs_unsupported); - } - handleArguments(C, Args, Inputs, Actions); // Builder to be used to build offloading actions. @@ -3822,15 +3857,8 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, // Queue linker inputs. if (Phase == phases::Link) { assert(Phase == PL.back() && "linking must be final compilation step."); - // Compilation phases are setup per language, however for SPIR-V the - // final linking phase is meaningless since the compilation phase - // produces the final binary. - // FIXME: OpenCL - we could strip linking phase out from OpenCL - // compilation phases if we could verify it is not needed by any target. - if (!C.getDefaultToolChain().getTriple().isSPIRV()) { - LinkerInputs.push_back(Current); - Current = nullptr; - } + LinkerInputs.push_back(Current); + Current = nullptr; break; } @@ -3888,6 +3916,13 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, } // Add a link action if necessary. + + if (LinkerInputs.empty()) { + Arg *FinalPhaseArg; + if (getFinalPhase(Args, &FinalPhaseArg) == phases::Link) + OffloadBuilder.appendDeviceLinkActions(Actions); + } + if (!LinkerInputs.empty()) { if (Action *Wrapper = OffloadBuilder.makeHostLinkAction()) LinkerInputs.push_back(Wrapper); @@ -4036,7 +4071,8 @@ Action *Driver::ConstructPhaseAction( OutputTy = types::TY_ModuleFile; } - if (Args.hasArg(options::OPT_fsyntax_only)) { + if (Args.hasArg(options::OPT_fsyntax_only) || + Args.hasArg(options::OPT_extract_api)) { // Syntax checks should not emit a PCH file OutputTy = types::TY_Nothing; } @@ -4064,6 +4100,8 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile); if (Args.hasArg(options::OPT_verify_pch)) return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing); + if (Args.hasArg(options::OPT_extract_api)) + return C.MakeAction<CompileJobAction>(Input, types::TY_API_INFO); return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC); } case phases::Backend: { diff --git contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp index d31529748b62..403fac76f060 100644 --- contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp +++ contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Path.h" #include "llvm/Support/SpecialCaseList.h" +#include "llvm/Support/AArch64TargetParser.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" @@ -641,10 +642,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, Args.hasFlag(options::OPT_fsanitize_memory_use_after_dtor, options::OPT_fno_sanitize_memory_use_after_dtor, MsanUseAfterDtor); + MsanParamRetval = Args.hasFlag( + options::OPT_fsanitize_memory_param_retval, + options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval); NeedPIE |= !(TC.getTriple().isOSLinux() && TC.getTriple().getArch() == llvm::Triple::x86_64); } else { MsanUseAfterDtor = false; + MsanParamRetval = false; } if (AllAddedKinds & SanitizerKind::Thread) { @@ -1096,6 +1101,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, if (MsanUseAfterDtor) CmdArgs.push_back("-fsanitize-memory-use-after-dtor"); + if (MsanParamRetval) + CmdArgs.push_back("-fsanitize-memory-param-retval"); + // FIXME: Pass these parameters as function attributes, not as -llvm flags. if (!TsanMemoryAccess) { CmdArgs.push_back("-mllvm"); diff --git contrib/llvm-project/clang/lib/Driver/ToolChain.cpp contrib/llvm-project/clang/lib/Driver/ToolChain.cpp index 50c89aaadc18..5fef1fb2ee5a 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChain.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChain.cpp @@ -75,17 +75,16 @@ ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, const ArgList &Args) : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)), CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) { - std::string RuntimePath = getRuntimePath(); - if (getVFS().exists(RuntimePath)) - getLibraryPaths().push_back(RuntimePath); - - std::string StdlibPath = getStdlibPath(); - if (getVFS().exists(StdlibPath)) - getFilePaths().push_back(StdlibPath); + auto addIfExists = [this](path_list &List, const std::string &Path) { + if (getVFS().exists(Path)) + List.push_back(Path); + }; - std::string CandidateLibPath = getArchSpecificLibPath(); - if (getVFS().exists(CandidateLibPath)) - getFilePaths().push_back(CandidateLibPath); + for (const auto &Path : getRuntimePaths()) + addIfExists(getLibraryPaths(), Path); + for (const auto &Path : getStdlibPaths()) + addIfExists(getFilePaths(), Path); + addIfExists(getFilePaths(), getArchSpecificLibPath()); } void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env) { @@ -110,6 +109,10 @@ bool ToolChain::useRelaxRelocations() const { return ENABLE_X86_RELAX_RELOCATIONS; } +bool ToolChain::defaultToIEEELongDouble() const { + return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux(); +} + SanitizerArgs ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const { SanitizerArgs SanArgs(*this, JobArgs, !SanitizerArgsChecked); @@ -485,16 +488,35 @@ const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args, return Args.MakeArgString(getCompilerRT(Args, Component, Type)); } -std::string ToolChain::getRuntimePath() const { - SmallString<128> P(D.ResourceDir); - llvm::sys::path::append(P, "lib", getTripleString()); - return std::string(P.str()); +ToolChain::path_list ToolChain::getRuntimePaths() const { + path_list Paths; + auto addPathForTriple = [this, &Paths](const llvm::Triple &Triple) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "lib", Triple.str()); + Paths.push_back(std::string(P.str())); + }; + + addPathForTriple(getTriple()); + + // Android targets may include an API level at the end. We still want to fall + // back on a path without the API level. + if (getTriple().isAndroid() && + getTriple().getEnvironmentName() != "android") { + llvm::Triple TripleWithoutLevel = getTriple(); + TripleWithoutLevel.setEnvironmentName("android"); + addPathForTriple(TripleWithoutLevel); + } + + return Paths; } -std::string ToolChain::getStdlibPath() const { +ToolChain::path_list ToolChain::getStdlibPaths() const { + path_list Paths; SmallString<128> P(D.Dir); llvm::sys::path::append(P, "..", "lib", getTripleString()); - return std::string(P.str()); + Paths.push_back(std::string(P.str())); + + return Paths; } std::string ToolChain::getArchSpecificLibPath() const { diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp index f282f04b7931..6899f9360da5 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp @@ -16,6 +16,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/InputInfo.h" #include "clang/Driver/Options.h" +#include "clang/Driver/Tool.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatAdapters.h" @@ -95,9 +96,9 @@ const char *AMDGCN::OpenMPLinker::constructLLVMLinkCommand( if (II.isFilename()) CmdArgs.push_back(II.getFilename()); + bool HasLibm = false; if (Args.hasArg(options::OPT_l)) { auto Lm = Args.getAllArgValues(options::OPT_l); - bool HasLibm = false; for (auto &Lib : Lm) { if (Lib == "m") { HasLibm = true; @@ -131,9 +132,8 @@ const char *AMDGCN::OpenMPLinker::constructLLVMLinkCommand( } AddStaticDeviceLibsLinking(C, *this, JA, Inputs, Args, CmdArgs, "amdgcn", - SubArchName, - /* bitcode SDL?*/ true, - /* PostClang Link? */ false); + SubArchName, /*isBitCodeSDL=*/true, + /*postClangLink=*/false); // Add an intermediate output file. CmdArgs.push_back("-o"); const char *OutputFileName = @@ -144,6 +144,26 @@ const char *AMDGCN::OpenMPLinker::constructLLVMLinkCommand( C.addCommand(std::make_unique<Command>( JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs, InputInfo(&JA, Args.MakeArgString(OutputFileName)))); + + // If we linked in libm definitions late we run another round of optimizations + // to inline the definitions and fold what is foldable. + if (HasLibm) { + ArgStringList OptCmdArgs; + const char *OptOutputFileName = + getOutputFileName(C, OutputFilePrefix, "-linked-opt", "bc"); + addLLCOptArg(Args, OptCmdArgs); + OptCmdArgs.push_back(OutputFileName); + OptCmdArgs.push_back("-o"); + OptCmdArgs.push_back(OptOutputFileName); + const char *OptExec = + Args.MakeArgString(getToolChain().GetProgramPath("opt")); + C.addCommand(std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileCurCP(), OptExec, OptCmdArgs, + InputInfo(&JA, Args.MakeArgString(OutputFileName)), + InputInfo(&JA, Args.MakeArgString(OptOutputFileName)))); + OutputFileName = OptOutputFileName; + } + return OutputFileName; } @@ -286,10 +306,22 @@ llvm::opt::DerivedArgList *AMDGPUOpenMPToolChain::TranslateArgs( const OptTable &Opts = getDriver().getOpts(); - if (DeviceOffloadKind != Action::OFK_OpenMP) { - for (Arg *A : Args) { - DAL->append(A); + if (DeviceOffloadKind == Action::OFK_OpenMP) { + for (Arg *A : Args) + if (!llvm::is_contained(*DAL, A)) + DAL->append(A); + + std::string Arch = DAL->getLastArgValue(options::OPT_march_EQ).str(); + if (Arch.empty()) { + checkSystemForAMDGPU(Args, *this, Arch); + DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), Arch); } + + return DAL; + } + + for (Arg *A : Args) { + DAL->append(A); } if (!BoundArch.empty()) { diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index be13d6d583ce..ca0ca4bf4eea 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -11,6 +11,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "llvm/Option/ArgList.h" +#include "llvm/Support/AArch64TargetParser.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/Host.h" @@ -98,12 +99,14 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text, Features.push_back("-sve2-sm4"); } - // +sve implies +f32mm if the base architecture is v8.6A, v8.7A, v9.1A or - // v9.2A. It isn't the case in general that sve implies both f64mm and f32mm + // +sve implies +f32mm if the base architecture is >= v8.6A (except v9A) + // It isn't the case in general that sve implies both f64mm and f32mm if ((ArchKind == llvm::AArch64::ArchKind::ARMV8_6A || ArchKind == llvm::AArch64::ArchKind::ARMV8_7A || + ArchKind == llvm::AArch64::ArchKind::ARMV8_8A || ArchKind == llvm::AArch64::ArchKind::ARMV9_1A || - ArchKind == llvm::AArch64::ArchKind::ARMV9_2A) && + ArchKind == llvm::AArch64::ArchKind::ARMV9_2A || + ArchKind == llvm::AArch64::ArchKind::ARMV9_3A) && Feature == "sve") Features.push_back("+f32mm"); } @@ -219,6 +222,7 @@ getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, void aarch64::getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, std::vector<StringRef> &Features, bool ForAS) { Arg *A; @@ -390,9 +394,11 @@ fp16_fml_fallthrough: } if (std::find(ItBegin, ItEnd, "+v8.4a") != ItEnd || + std::find(ItBegin, ItEnd, "+v8.8a") != ItEnd || std::find(ItBegin, ItEnd, "+v9a") != ItEnd || std::find(ItBegin, ItEnd, "+v9.1a") != ItEnd || - std::find(ItBegin, ItEnd, "+v9.2a") != ItEnd) { + std::find(ItBegin, ItEnd, "+v9.2a") != ItEnd || + std::find(ItBegin, ItEnd, "+v9.3a") != ItEnd) { if (HasCrypto && !NoCrypto) { // Check if we have NOT disabled an algorithm with something like: // +crypto, -algorithm @@ -451,7 +457,8 @@ fp16_fml_fallthrough: } } - const char *Archs[] = {"+v8.6a", "+v8.7a", "+v9.1a", "+v9.2a"}; + const char *Archs[] = {"+v8.6a", "+v8.7a", "+v8.8a", + "+v9.1a", "+v9.2a", "+v9.3a"}; auto Pos = std::find_first_of(Features.begin(), Features.end(), std::begin(Archs), std::end(Archs)); if (Pos != std::end(Features)) @@ -459,10 +466,16 @@ fp16_fml_fallthrough: if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) { - if (A->getOption().matches(options::OPT_mno_unaligned_access)) + if (A->getOption().matches(options::OPT_mno_unaligned_access)) { Features.push_back("+strict-align"); - } else if (Triple.isOSOpenBSD()) + if (!ForAS) + CmdArgs.push_back("-Wunaligned-access"); + } + } else if (Triple.isOSOpenBSD()) { Features.push_back("+strict-align"); + if (!ForAS) + CmdArgs.push_back("-Wunaligned-access"); + } if (Args.hasArg(options::OPT_ffixed_x1)) Features.push_back("+reserve-x1"); diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.h contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.h index d47c402d4a42..0cdc2ec725e0 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.h +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.h @@ -22,6 +22,7 @@ namespace aarch64 { void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, std::vector<llvm::StringRef> &Features, bool ForAS); diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp index 4013cf230026..16af9f6d7129 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -12,6 +12,7 @@ #include "clang/Driver/Options.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Option/ArgList.h" +#include "llvm/Support/ARMTargetParser.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/Host.h" @@ -769,10 +770,12 @@ fp16_fml_fallthrough: } // Kernel code has more strict alignment requirements. - if (KernelOrKext) + if (KernelOrKext) { Features.push_back("+strict-align"); - else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, - options::OPT_munaligned_access)) { + if (!ForAS) + CmdArgs.push_back("-Wunaligned-access"); + } else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, + options::OPT_munaligned_access)) { if (A->getOption().matches(options::OPT_munaligned_access)) { // No v6M core supports unaligned memory access (v6M ARM ARM A3.2). if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m) @@ -781,8 +784,11 @@ fp16_fml_fallthrough: // access either. else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline) D.Diag(diag::err_target_unsupported_unaligned) << "v8m.base"; - } else + } else { Features.push_back("+strict-align"); + if (!ForAS) + CmdArgs.push_back("-Wunaligned-access"); + } } else { // Assume pre-ARMv6 doesn't support unaligned accesses. // @@ -801,14 +807,23 @@ fp16_fml_fallthrough: int VersionNum = getARMSubArchVersionNumber(Triple); if (Triple.isOSDarwin() || Triple.isOSNetBSD()) { if (VersionNum < 6 || - Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m) + Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m) { Features.push_back("+strict-align"); + if (!ForAS) + CmdArgs.push_back("-Wunaligned-access"); + } } else if (Triple.isOSLinux() || Triple.isOSNaCl() || Triple.isOSWindows()) { - if (VersionNum < 7) + if (VersionNum < 7) { Features.push_back("+strict-align"); - } else + if (!ForAS) + CmdArgs.push_back("-Wunaligned-access"); + } + } else { Features.push_back("+strict-align"); + if (!ForAS) + CmdArgs.push_back("-Wunaligned-access"); + } } // llvm does not support reserving registers in general. There is support diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h index 881b63bd36b9..862a2f2796be 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h @@ -13,6 +13,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Option/Option.h" +#include "llvm/Support/ARMTargetParser.h" #include "llvm/Support/TargetParser.h" #include <string> #include <vector> diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp index 65347a38490e..4386e395bc6c 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp @@ -33,6 +33,7 @@ #include "clang/Driver/InputInfo.h" #include "clang/Driver/Options.h" #include "clang/Driver/SanitizerArgs.h" +#include "clang/Driver/Types.h" #include "clang/Driver/XRayArgs.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Config/llvm-config.h" @@ -346,7 +347,8 @@ static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, case llvm::Triple::aarch64: case llvm::Triple::aarch64_32: case llvm::Triple::aarch64_be: - aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, ForAS); + aarch64::getAArch64TargetFeatures(D, Triple, Args, CmdArgs, Features, + ForAS); break; case llvm::Triple::x86: case llvm::Triple::x86_64: @@ -1115,7 +1117,7 @@ static void RenderDebugInfoCompressionArgs(const ArgList &Args, StringRef Value = A->getValue(); if (Value == "none") { CmdArgs.push_back("--compress-debug-sections=none"); - } else if (Value == "zlib" || Value == "zlib-gnu") { + } else if (Value == "zlib") { if (llvm::zlib::isAvailable()) { CmdArgs.push_back( Args.MakeArgString("--compress-debug-sections=" + Twine(Value))); @@ -1929,6 +1931,11 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, } } + if (Args.getLastArg(options::OPT_mfix4300)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-mfix4300"); + } + if (Arg *A = Args.getLastArg(options::OPT_G)) { StringRef v = A->getValue(); CmdArgs.push_back("-mllvm"); @@ -2055,7 +2062,7 @@ void Clang::AddPPCTargetArgs(const ArgList &Args, } } - bool IEEELongDouble = false; + bool IEEELongDouble = getToolChain().defaultToIEEELongDouble(); for (const Arg *A : Args.filtered(options::OPT_mabi_EQ)) { StringRef V = A->getValue(); if (V == "ieeelongdouble") @@ -2897,6 +2904,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, AssociativeMath = true; ReciprocalMath = true; SignedZeros = false; + ApproxFunc = true; TrappingMath = false; FPExceptionBehavior = ""; break; @@ -2904,6 +2912,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, AssociativeMath = false; ReciprocalMath = false; SignedZeros = true; + ApproxFunc = false; TrappingMath = true; FPExceptionBehavior = "strict"; @@ -2923,6 +2932,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, MathErrno = false; AssociativeMath = true; ReciprocalMath = true; + ApproxFunc = true; SignedZeros = false; TrappingMath = false; RoundingFPMath = false; @@ -2938,6 +2948,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, MathErrno = TC.IsMathErrnoDefault(); AssociativeMath = false; ReciprocalMath = false; + ApproxFunc = false; SignedZeros = true; // -fno_fast_math restores default denormal and fpcontract handling DenormalFPMath = DefaultDenormalFPMath; @@ -2956,7 +2967,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, // If -ffp-model=strict has been specified on command line but // subsequent options conflict then emit warning diagnostic. if (HonorINFs && HonorNaNs && !AssociativeMath && !ReciprocalMath && - SignedZeros && TrappingMath && RoundingFPMath && + SignedZeros && TrappingMath && RoundingFPMath && !ApproxFunc && DenormalFPMath == llvm::DenormalMode::getIEEE() && DenormalFP32Math == llvm::DenormalMode::getIEEE() && FPContract.equals("off")) @@ -2989,7 +3000,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, CmdArgs.push_back("-fmath-errno"); if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros && - !TrappingMath) + ApproxFunc && !TrappingMath) CmdArgs.push_back("-menable-unsafe-fp-math"); if (!SignedZeros) @@ -3040,7 +3051,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, // -ffast-math enables the __FAST_MATH__ preprocessor macro, but check for the // individual features enabled by -ffast-math instead of the option itself as // that's consistent with gcc's behaviour. - if (!HonorINFs && !HonorNaNs && !MathErrno && AssociativeMath && + if (!HonorINFs && !HonorNaNs && !MathErrno && AssociativeMath && ApproxFunc && ReciprocalMath && !SignedZeros && !TrappingMath && !RoundingFPMath) { CmdArgs.push_back("-ffast-math"); if (FPModel.equals("fast")) { @@ -3217,9 +3228,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, return; } // Check whether the target subarch supports the hardware TLS register - if (arm::getARMSubArchVersionNumber(EffectiveTriple) < 7 && - llvm::ARM::parseArch(EffectiveTriple.getArchName()) != - llvm::ARM::ArchKind::ARMV6T2) { + if (!arm::isHardTPSupported(EffectiveTriple)) { D.Diag(diag::err_target_unsupported_tp_hard) << EffectiveTriple.getArchName(); return; @@ -4589,6 +4598,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } else if (JA.getType() == types::TY_RewrittenLegacyObjC) { CmdArgs.push_back("-rewrite-objc"); rewriteKind = RK_Fragile; + } else if (JA.getType() == types::TY_API_INFO) { + CmdArgs.push_back("-extract-api"); } else { assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!"); } @@ -5310,7 +5321,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // as errors, but until then, we can live with a warning being emitted by the // compiler. This way, Clang can be used to compile code with scalable vectors // and identify possible issues. - if (isa<BackendJobAction>(JA)) { + if (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) || + isa<BackendJobAction>(JA)) { CmdArgs.push_back("-mllvm"); CmdArgs.push_back("-treat-scalable-fixed-error-as-warning"); } @@ -5813,6 +5825,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-ftype-visibility"); CmdArgs.push_back("default"); } + } else if (IsOpenMPDevice) { + // When compiling for the OpenMP device we want protected visibility by + // default. This prevents the device from accidenally preempting code on the + // host, makes the system more robust, and improves performance. + CmdArgs.push_back("-fvisibility"); + CmdArgs.push_back("protected"); } if (!RawTriple.isPS4()) @@ -5992,6 +6010,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + Args.AddLastArg(CmdArgs, options::OPT_fms_hotpatch); + if (TC.SupportsProfiling()) { Args.AddLastArg(CmdArgs, options::OPT_pg); @@ -6149,6 +6169,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(Twine("-fcf-protection=") + A->getValue())); } + if (IsUsingLTO) + Args.AddLastArg(CmdArgs, options::OPT_mibt_seal); + // Forward -f options with positive and negative forms; we translate these by // hand. Do not propagate PGO options to the GPU-side compilations as the // profile info is for the host-side compilation only. @@ -6663,6 +6686,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_dM); Args.AddLastArg(CmdArgs, options::OPT_dD); + Args.AddLastArg(CmdArgs, options::OPT_dI); Args.AddLastArg(CmdArgs, options::OPT_fmax_tokens_EQ); diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.h contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.h index 00e0490e069b..013cd2341e17 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.h +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_Clang_H -#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_Clang_H +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CLANG_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CLANG_H #include "MSVC.h" #include "clang/Basic/DebugInfoOptions.h" diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp index 407f81a2ae09..1d30090ca21c 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -286,13 +286,13 @@ void tools::addLinkerCompressDebugSectionsOption( const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) { // GNU ld supports --compress-debug-sections=none|zlib|zlib-gnu|zlib-gabi - // whereas zlib is an alias to zlib-gabi. Therefore -gz=none|zlib|zlib-gnu - // are translated to --compress-debug-sections=none|zlib|zlib-gnu. - // -gz is not translated since ld --compress-debug-sections option requires an + // whereas zlib is an alias to zlib-gabi and zlib-gnu is obsoleted. Therefore + // -gz=none|zlib are translated to --compress-debug-sections=none|zlib. -gz + // is not translated since ld --compress-debug-sections option requires an // argument. if (const Arg *A = Args.getLastArg(options::OPT_gz_EQ)) { StringRef V = A->getValue(); - if (V == "none" || V == "zlib" || V == "zlib-gnu") + if (V == "none" || V == "zlib") CmdArgs.push_back(Args.MakeArgString("--compress-debug-sections=" + V)); else TC.getDriver().Diag(diag::err_drv_unsupported_option_argument) @@ -832,6 +832,10 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, return; } + // Always link the static runtime for executable. + if (SanArgs.needsAsanRt()) + HelperStaticRuntimes.push_back("asan_static"); + // Each static runtime that has a DSO counterpart above is excluded below, // but runtimes that exist only as static are not affected by needsSharedRt. @@ -1186,10 +1190,9 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { options::OPT_fpic, options::OPT_fno_pic, options::OPT_fPIE, options::OPT_fno_PIE, options::OPT_fpie, options::OPT_fno_pie); - if (Triple.isOSWindows() && LastPICArg && - LastPICArg == - Args.getLastArg(options::OPT_fPIC, options::OPT_fpic, - options::OPT_fPIE, options::OPT_fpie)) { + if (Triple.isOSWindows() && !Triple.isOSCygMing() && LastPICArg && + LastPICArg == Args.getLastArg(options::OPT_fPIC, options::OPT_fpic, + options::OPT_fPIE, options::OPT_fpie)) { ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target) << LastPICArg->getSpelling() << Triple.str(); if (Triple.getArch() == llvm::Triple::x86_64) @@ -1724,7 +1727,7 @@ bool tools::GetSDLFromOffloadArchive( std::string OutputLib = D.GetTemporaryPath( Twine(Prefix + Lib + "-" + Arch + "-" + Target).str(), "a"); - C.addTempFile(C.getArgs().MakeArgString(OutputLib.c_str())); + C.addTempFile(C.getArgs().MakeArgString(OutputLib)); ArgStringList CmdArgs; SmallString<128> DeviceTriple; @@ -1747,20 +1750,20 @@ bool tools::GetSDLFromOffloadArchive( T.getToolChain().GetProgramPath("clang-offload-bundler")); ArgStringList UBArgs; - UBArgs.push_back(C.getArgs().MakeArgString(UnbundleArg.c_str())); - UBArgs.push_back(C.getArgs().MakeArgString(TypeArg.c_str())); - UBArgs.push_back(C.getArgs().MakeArgString(InputArg.c_str())); - UBArgs.push_back(C.getArgs().MakeArgString(OffloadArg.c_str())); - UBArgs.push_back(C.getArgs().MakeArgString(OutputArg.c_str())); + UBArgs.push_back(C.getArgs().MakeArgString(UnbundleArg)); + UBArgs.push_back(C.getArgs().MakeArgString(TypeArg)); + UBArgs.push_back(C.getArgs().MakeArgString(InputArg)); + UBArgs.push_back(C.getArgs().MakeArgString(OffloadArg)); + UBArgs.push_back(C.getArgs().MakeArgString(OutputArg)); // Add this flag to not exit from clang-offload-bundler if no compatible // code object is found in heterogenous archive library. std::string AdditionalArgs("-allow-missing-bundles"); - UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs.c_str())); + UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs)); C.addCommand(std::make_unique<Command>( JA, T, ResponseFileSupport::AtFileCurCP(), UBProgram, UBArgs, Inputs, - InputInfo(&JA, C.getArgs().MakeArgString(OutputLib.c_str())))); + InputInfo(&JA, C.getArgs().MakeArgString(OutputLib)))); if (postClangLink) CC1Args.push_back("-mlink-builtin-bitcode"); diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp index ee573b89bed1..7324339efaa6 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp @@ -612,8 +612,9 @@ void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(CubinF); } - AddStaticDeviceLibsLinking(C, *this, JA, Inputs, Args, CmdArgs, "nvptx", GPUArch, - false, false); + AddStaticDeviceLibsLinking(C, *this, JA, Inputs, Args, CmdArgs, "nvptx", + GPUArch, /*isBitCodeSDL=*/false, + /*postClangLink=*/false); // Find nvlink and pass it as "--nvlink-path=" argument of // clang-nvlink-wrapper. @@ -752,8 +753,9 @@ void CudaToolChain::addClangTargetOptions( addOpenMPDeviceRTL(getDriver(), DriverArgs, CC1Args, BitcodeSuffix, getTriple()); - AddStaticDeviceLibsPostLinking(getDriver(), DriverArgs, CC1Args, "nvptx", GpuArch, - /* bitcode SDL?*/ true, /* PostClang Link? */ true); + AddStaticDeviceLibsPostLinking(getDriver(), DriverArgs, CC1Args, "nvptx", + GpuArch, /*isBitCodeSDL=*/true, + /*postClangLink=*/true); } } diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp index de635f5816cf..05c58a8f43a8 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -247,7 +247,8 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, assert(Output.isNothing() && "Invalid output."); } - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, + options::OPT_r)) { const char *crt1 = nullptr; if (!Args.hasArg(options::OPT_shared)) { if (Args.hasArg(options::OPT_pg)) @@ -295,7 +296,8 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, unsigned Major = ToolChain.getTriple().getOSMajorVersion(); bool Profiling = Args.hasArg(options::OPT_pg) && Major != 0 && Major < 14; - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, + options::OPT_r)) { // Use the static OpenMP runtime with -static-openmp bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Args.hasArg(options::OPT_static); @@ -358,7 +360,8 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, + options::OPT_r)) { if (Args.hasArg(options::OPT_shared) || IsPIE) CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o"))); else diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp index a7afec6963a1..bd1600d060c8 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -109,7 +109,8 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, + options::OPT_r)) { if (!Args.hasArg(options::OPT_shared)) { CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("Scrt1.o"))); } @@ -131,7 +132,8 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); ToolChain.addProfileRTLibs(Args, CmdArgs); - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, + options::OPT_r)) { if (Args.hasArg(options::OPT_static)) CmdArgs.push_back("-Bdynamic"); @@ -191,9 +193,11 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple, auto FilePaths = [&](const Multilib &M) -> std::vector<std::string> { std::vector<std::string> FP; - SmallString<128> P(getStdlibPath()); - llvm::sys::path::append(P, M.gccSuffix()); - FP.push_back(std::string(P.str())); + for (const std::string &Path : getStdlibPaths()) { + SmallString<128> P(Path); + llvm::sys::path::append(P, M.gccSuffix()); + FP.push_back(std::string(P.str())); + } return FP; }; diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp index 7aeadd84dfee..7a9570a686f4 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp @@ -487,7 +487,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, + options::OPT_r)) { if (!isAndroid && !IsIAMCU) { const char *crt1 = nullptr; if (!Args.hasArg(options::OPT_shared)) { @@ -563,7 +564,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, getToolChain().addProfileRTLibs(Args, CmdArgs); if (D.CCCIsCXX() && - !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { + !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, + options::OPT_r)) { if (ToolChain.ShouldLinkCXXStdlib(Args)) { bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && !Args.hasArg(options::OPT_static); @@ -578,7 +580,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Silence warnings when linking C code with a C++ '-stdlib' argument. Args.ClaimAllArgs(options::OPT_stdlib_EQ); - if (!Args.hasArg(options::OPT_nostdlib)) { + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r)) { if (!Args.hasArg(options::OPT_nodefaultlibs)) { if (IsStatic || IsStaticPIE) CmdArgs.push_back("--start-group"); @@ -692,7 +694,7 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, CmdArgs.push_back("--compress-debug-sections"); } else { StringRef Value = A->getValue(); - if (Value == "none" || Value == "zlib" || Value == "zlib-gnu") { + if (Value == "none" || Value == "zlib") { CmdArgs.push_back( Args.MakeArgString("--compress-debug-sections=" + Twine(Value))); } else { diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp index e413640abad3..af74b108e04e 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp @@ -324,6 +324,12 @@ ToolChain::RuntimeLibType Linux::GetDefaultRuntimeLibType() const { return Generic_ELF::GetDefaultRuntimeLibType(); } +unsigned Linux::GetDefaultDwarfVersion() const { + if (getTriple().isAndroid()) + return 4; + return ToolChain::GetDefaultDwarfVersion(); +} + ToolChain::CXXStdlibType Linux::GetDefaultCXXStdlibType() const { if (getTriple().isAndroid()) return ToolChain::CST_Libcxx; diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.h contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.h index a5ec33bd44f1..a5648d79d655 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.h +++ contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.h @@ -40,6 +40,7 @@ public: void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; RuntimeLibType GetDefaultRuntimeLibType() const override; + unsigned GetDefaultDwarfVersion() const override; CXXStdlibType GetDefaultCXXStdlibType() const override; bool IsAArch64OutlineAtomicsDefault(const llvm::opt::ArgList &Args) const override; diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp index 66e9d8ab525a..18cef288f018 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp @@ -47,7 +47,14 @@ // Make sure this comes before MSVCSetupApi.h #include <comdef.h> +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif #include "MSVCSetupApi.h" +#ifdef __clang__ +#pragma clang diagnostic pop +#endif #include "llvm/Support/COM.h" _COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration)); _COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2)); @@ -511,6 +518,11 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7)) CmdArgs.push_back("-debug"); + // If we specify /hotpatch, let the linker add padding in front of each + // function, like MSVC does. + if (Args.hasArg(options::OPT_fms_hotpatch, options::OPT__SLASH_hotpatch)) + CmdArgs.push_back("-functionpadmin"); + // Pass on /Brepro if it was passed to the compiler. // Note that /Brepro maps to -mno-incremental-linker-compatible. bool DefaultIncrementalLinkerCompatible = @@ -1333,6 +1345,15 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, "Include", windowsSDKIncludeVersion, "winrt"); + if (major >= 10) { + llvm::VersionTuple Tuple; + if (!Tuple.tryParse(windowsSDKIncludeVersion) && + Tuple.getSubminor().getValueOr(0) >= 17134) { + AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, + "Include", windowsSDKIncludeVersion, + "cppwinrt"); + } + } } else { AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, "Include"); diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.h contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.h index 8f033de09bf6..c842773996ed 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.h +++ contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.h @@ -69,6 +69,10 @@ public: return llvm::DebuggerKind::Default; } + unsigned GetDefaultDwarfVersion() const override { + return 4; + } + enum class SubDirectoryType { Bin, Include, diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/MSVCSetupApi.h contrib/llvm-project/clang/lib/Driver/ToolChains/MSVCSetupApi.h index a890b85fd5e9..28e6e3e08e37 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/MSVCSetupApi.h +++ contrib/llvm-project/clang/lib/Driver/ToolChains/MSVCSetupApi.h @@ -28,6 +28,11 @@ #pragma once +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif + // Constants // #ifndef E_NOTFOUND @@ -512,3 +517,7 @@ STDMETHODIMP GetSetupConfiguration(_Out_ ISetupConfiguration **ppConfiguration, #ifdef __cplusplus } #endif + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp index ecce2f062bd7..0501f9737404 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp @@ -164,6 +164,9 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--enable-auto-image-base"); } + if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) + CmdArgs.push_back("--no-demangle"); + CmdArgs.push_back("-o"); const char *OutputFile = Output.getFilename(); // GCC implicitly adds an .exe extension if it is given an output file name @@ -486,10 +489,7 @@ bool toolchains::MinGW::isPIEDefault(const llvm::opt::ArgList &Args) const { return false; } -bool toolchains::MinGW::isPICDefaultForced() const { - return getArch() == llvm::Triple::x86_64 || - getArch() == llvm::Triple::aarch64; -} +bool toolchains::MinGW::isPICDefaultForced() const { return true; } llvm::ExceptionHandling toolchains::MinGW::GetExceptionModel(const ArgList &Args) const { diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.cpp index af2e3a21a0af..e480d8bd8703 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.cpp @@ -8,11 +8,51 @@ #include "PPCLinux.h" #include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +using namespace clang::driver; using namespace clang::driver::toolchains; using namespace llvm::opt; +using namespace llvm::sys; + +// Glibc older than 2.32 doesn't fully support IEEE float128. Here we check +// glibc version by looking at dynamic linker name. +static bool GlibcSupportsFloat128(const std::string &Linker) { + llvm::SmallVector<char, 16> Path; + + // Resolve potential symlinks to linker. + if (fs::real_path(Linker, Path)) + return false; + llvm::StringRef LinkerName = + path::filename(llvm::StringRef(Path.data(), Path.size())); + + // Since glibc 2.34, the installed .so file is not symlink anymore. But we can + // still safely assume it's newer than 2.32. + if (LinkerName.startswith("ld64.so")) + return true; + + if (!LinkerName.startswith("ld-2.")) + return false; + unsigned Minor = (LinkerName[5] - '0') * 10 + (LinkerName[6] - '0'); + if (Minor < 32) + return false; + + return true; +} + +PPCLinuxToolChain::PPCLinuxToolChain(const Driver &D, + const llvm::Triple &Triple, + const llvm::opt::ArgList &Args) + : Linux(D, Triple, Args) { + if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) { + StringRef ABIName = A->getValue(); + if (ABIName == "ieeelongdouble" && !SupportIEEEFloat128(D, Triple, Args)) + D.Diag(diag::warn_drv_unsupported_float_abi_by_lib) << ABIName; + } +} void PPCLinuxToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { @@ -26,3 +66,20 @@ void PPCLinuxToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, Linux::AddClangSystemIncludeArgs(DriverArgs, CC1Args); } + +bool PPCLinuxToolChain::SupportIEEEFloat128( + const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args) const { + if (!Triple.isLittleEndian() || !Triple.isPPC64()) + return false; + + if (Args.hasArg(options::OPT_nostdlib, options::OPT_nostdlibxx)) + return true; + + bool HasUnsupportedCXXLib = + ToolChain::GetCXXStdlibType(Args) == CST_Libcxx && + GCCInstallation.getVersion().isOlderThan(12, 1, 0); + + return GlibcSupportsFloat128(Linux::getDynamicLinker(Args)) && + !(D.CCCIsCXX() && HasUnsupportedCXXLib); +} diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.h contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.h index b3ef7b61dc3a..e0318ae8a3a2 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.h +++ contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.h @@ -18,12 +18,15 @@ namespace toolchains { class LLVM_LIBRARY_VISIBILITY PPCLinuxToolChain : public Linux { public: PPCLinuxToolChain(const Driver &D, const llvm::Triple &Triple, - const llvm::opt::ArgList &Args) - : Linux(D, Triple, Args) {} + const llvm::opt::ArgList &Args); void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + +private: + bool SupportIEEEFloat128(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args) const; }; } // end namespace toolchains diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp index 5783a733983a..bcf9147833dd 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp @@ -23,8 +23,6 @@ using namespace clang::driver; using namespace clang; using namespace llvm::opt; -using clang::driver::tools::AddLinkerInputs; - void tools::PS4cpu::addProfileRTArgs(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { if ((Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.cpp index 50d03e79bbb0..27de69550853 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.cpp @@ -70,3 +70,24 @@ clang::driver::Tool *SPIRVToolChain::getTool(Action::ActionClass AC) const { } return ToolChain::getTool(AC); } +clang::driver::Tool *SPIRVToolChain::buildLinker() const { + return new tools::SPIRV::Linker(*this); +} + +void SPIRV::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const ToolChain &ToolChain = getToolChain(); + std::string Linker = ToolChain.GetProgramPath(getShortName()); + ArgStringList CmdArgs; + AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), + Args.MakeArgString(Linker), CmdArgs, + Inputs, Output)); +} diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.h contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.h index 229f7018e3b5..a16ae3ca51fa 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.h +++ contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.h @@ -39,6 +39,17 @@ public: const char *LinkingOutput) const override; }; +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { +public: + Linker(const ToolChain &TC) : Tool("SPIRV::Linker", "spirv-link", TC) {} + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; + } // namespace SPIRV } // namespace tools @@ -68,6 +79,7 @@ public: protected: clang::driver::Tool *getTool(Action::ActionClass AC) const override; + Tool *buildLinker() const override; private: clang::driver::Tool *getTranslator() const; diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp index 4cdeec7f9d8a..1e43796be1ff 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp @@ -48,7 +48,8 @@ VEToolChain::VEToolChain(const Driver &D, const llvm::Triple &Triple, // ${BINPATH}/../lib/ve-unknown-linux-gnu, (== getStdlibPath) // ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPath) // ${SYSROOT}/opt/nec/ve/lib, - getFilePaths().push_back(getStdlibPath()); + for (auto &Path : getStdlibPaths()) + getFilePaths().push_back(std::move(Path)); getFilePaths().push_back(getArchSpecificLibPath()); getFilePaths().push_back(computeSysRoot() + "/opt/nec/ve/lib"); } diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp index a7298a9a71bf..3614272a5f74 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -76,7 +76,7 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, ToolChain.AddFilePathLibArgs(Args, CmdArgs); const char *Crt1 = "crt1.o"; - const char *Entry = NULL; + const char *Entry = nullptr; // If crt1-command.o exists, it supports new-style commands, so use it. // Otherwise, use the old crt1.o. This is a temporary transition measure. diff --git contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.h contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.h index c84e59675946..b4c3082a089a 100644 --- contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.h +++ contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.h @@ -51,6 +51,7 @@ private: bool hasBlocksRuntime() const override; bool SupportsProfiling() const override; bool HasNativeLLVMSupport() const override; + unsigned GetDefaultDwarfVersion() const override { return 4; } void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, diff --git contrib/llvm-project/clang/lib/Driver/Types.cpp contrib/llvm-project/clang/lib/Driver/Types.cpp index 1bd187ad2fc0..8f6adc6c2ad1 100644 --- contrib/llvm-project/clang/lib/Driver/Types.cpp +++ contrib/llvm-project/clang/lib/Driver/Types.cpp @@ -143,6 +143,7 @@ bool types::isAcceptedByClang(ID Id) { case TY_CXXModule: case TY_PP_CXXModule: case TY_AST: case TY_ModuleFile: case TY_PCH: case TY_LLVM_IR: case TY_LLVM_BC: + case TY_API_INFO: return true; } } diff --git contrib/llvm-project/clang/lib/Edit/RewriteObjCFoundationAPI.cpp contrib/llvm-project/clang/lib/Edit/RewriteObjCFoundationAPI.cpp index a3d388a5ae44..589bf8d216ed 100644 --- contrib/llvm-project/clang/lib/Edit/RewriteObjCFoundationAPI.cpp +++ contrib/llvm-project/clang/lib/Edit/RewriteObjCFoundationAPI.cpp @@ -704,7 +704,7 @@ static bool getLiteralInfo(SourceRange literalRange, } }; - while (1) { + while (true) { if (Suff::has("u", text)) { UpperU = false; } else if (Suff::has("U", text)) { diff --git contrib/llvm-project/clang/lib/Format/AffectedRangeManager.cpp contrib/llvm-project/clang/lib/Format/AffectedRangeManager.cpp index 7ad1f7070d0a..f69f65c5ddf1 100644 --- contrib/llvm-project/clang/lib/Format/AffectedRangeManager.cpp +++ contrib/llvm-project/clang/lib/Format/AffectedRangeManager.cpp @@ -27,6 +27,7 @@ bool AffectedRangeManager::computeAffectedLines( const AnnotatedLine *PreviousLine = nullptr; while (I != E) { AnnotatedLine *Line = *I; + assert(Line->First); Line->LeadingEmptyLinesAffected = affectsLeadingEmptyLines(*Line->First); // If a line is part of a preprocessor directive, it needs to be formatted @@ -59,13 +60,10 @@ bool AffectedRangeManager::computeAffectedLines( bool AffectedRangeManager::affectsCharSourceRange( const CharSourceRange &Range) { - for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(), - E = Ranges.end(); - I != E; ++I) { - if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), I->getBegin()) && - !SourceMgr.isBeforeInTranslationUnit(I->getEnd(), Range.getBegin())) + for (const CharSourceRange &R : Ranges) + if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), R.getBegin()) && + !SourceMgr.isBeforeInTranslationUnit(R.getEnd(), Range.getBegin())) return true; - } return false; } @@ -116,6 +114,7 @@ bool AffectedRangeManager::nonPPLineAffected( // affected. bool SomeFirstChildAffected = false; + assert(Line->First); for (FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) { // Determine whether 'Tok' was affected. if (affectsTokenRange(*Tok, *Tok, IncludeLeadingNewlines)) diff --git contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp index 4225d6b67b0e..b66584652bc8 100644 --- contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp +++ contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp @@ -341,6 +341,8 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { if (State.Stack.back().BreakBeforeClosingBrace && Current.closesBlockOrBlockTypeList(Style)) return true; + if (State.Stack.back().BreakBeforeClosingParen && Current.is(tok::r_paren)) + return true; if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection) return true; if (Style.Language == FormatStyle::LK_ObjC && @@ -485,7 +487,8 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { // different LineFormatter would be used otherwise. if (Previous.ClosesTemplateDeclaration) return Style.AlwaysBreakTemplateDeclarations != FormatStyle::BTDS_No; - if (Previous.is(TT_FunctionAnnotationRParen)) + if (Previous.is(TT_FunctionAnnotationRParen) && + State.Line->Type != LT_PreprocessorDirective) return true; if (Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) && Current.isNot(TT_LeadingJavaAnnotation)) @@ -540,13 +543,15 @@ unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline, bool DryRun, unsigned ExtraSpaces) { const FormatToken &Current = *State.NextToken; + assert(State.NextToken->Previous); + const FormatToken &Previous = *State.NextToken->Previous; assert(!State.Stack.empty()); State.NoContinuation = false; if ((Current.is(TT_ImplicitStringLiteral) && - (Current.Previous->Tok.getIdentifierInfo() == nullptr || - Current.Previous->Tok.getIdentifierInfo()->getPPKeywordID() == + (Previous.Tok.getIdentifierInfo() == nullptr || + Previous.Tok.getIdentifierInfo()->getPPKeywordID() == tok::pp_not_keyword))) { unsigned EndColumn = SourceMgr.getSpellingColumnNumber(Current.WhitespaceRange.getEnd()); @@ -576,7 +581,9 @@ unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline, void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, unsigned ExtraSpaces) { FormatToken &Current = *State.NextToken; + assert(State.NextToken->Previous); const FormatToken &Previous = *State.NextToken->Previous; + if (Current.is(tok::equal) && (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) && State.Stack.back().VariablePos == 0) { @@ -638,10 +645,12 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, State.Stack.back().ColonPos = FirstColonPos; } - // In "AlwaysBreak" mode, enforce wrapping directly after the parenthesis by - // disallowing any further line breaks if there is no line break after the - // opening parenthesis. Don't break if it doesn't conserve columns. - if (Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak && + // In "AlwaysBreak" or "BlockIndent" mode, enforce wrapping directly after the + // parenthesis by disallowing any further line breaks if there is no line + // break after the opening parenthesis. Don't break if it doesn't conserve + // columns. + if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak || + Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) && (Previous.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) || (Previous.is(tok::l_brace) && Previous.isNot(BK_Block) && Style.Cpp11BracedListStyle)) && @@ -770,6 +779,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, bool DryRun) { FormatToken &Current = *State.NextToken; + assert(State.NextToken->Previous); const FormatToken &Previous = *State.NextToken->Previous; // Extra penalty that needs to be added because of the way certain line @@ -942,6 +952,10 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, opensProtoMessageField(*PreviousNonComment, Style))) State.Stack.back().BreakBeforeClosingBrace = true; + if (PreviousNonComment && PreviousNonComment->is(tok::l_paren)) + State.Stack.back().BreakBeforeClosingParen = + Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; + if (State.Stack.back().AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializater list in a constructor, this should not @@ -1036,6 +1050,9 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { (!Current.Next || Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) return State.Stack[State.Stack.size() - 2].LastSpace; + if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && + Current.is(tok::r_paren) && State.Stack.size() > 1) + return State.Stack[State.Stack.size() - 2].LastSpace; if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope()) return State.Stack[State.Stack.size() - 2].LastSpace; if (Current.is(tok::identifier) && Current.Next && @@ -1288,10 +1305,9 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State, State.Stack[i].NoLineBreak = true; State.Stack[State.Stack.size() - 2].NestedBlockInlined = false; } - if (Previous && - (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) || - Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr)) && - !Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) { + if (Previous && (Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) || + (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) && + !Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)))) { State.Stack.back().NestedBlockInlined = !Newline && hasNestedBlockInlined(Previous, Current, Style); } diff --git contrib/llvm-project/clang/lib/Format/ContinuationIndenter.h contrib/llvm-project/clang/lib/Format/ContinuationIndenter.h index b1b2611263a9..0eb53cbd0293 100644 --- contrib/llvm-project/clang/lib/Format/ContinuationIndenter.h +++ contrib/llvm-project/clang/lib/Format/ContinuationIndenter.h @@ -203,15 +203,15 @@ struct ParenState { bool AvoidBinPacking, bool NoLineBreak) : Tok(Tok), Indent(Indent), LastSpace(LastSpace), NestedBlockIndent(Indent), IsAligned(false), - BreakBeforeClosingBrace(false), AvoidBinPacking(AvoidBinPacking), - BreakBeforeParameter(false), NoLineBreak(NoLineBreak), - NoLineBreakInOperand(false), LastOperatorWrapped(true), - ContainsLineBreak(false), ContainsUnwrappedBuilder(false), - AlignColons(true), ObjCSelectorNameFound(false), - HasMultipleNestedBlocks(false), NestedBlockInlined(false), - IsInsideObjCArrayLiteral(false), IsCSharpGenericTypeConstraint(false), - IsChainedConditional(false), IsWrappedConditional(false), - UnindentOperator(false) {} + BreakBeforeClosingBrace(false), BreakBeforeClosingParen(false), + AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false), + NoLineBreak(NoLineBreak), NoLineBreakInOperand(false), + LastOperatorWrapped(true), ContainsLineBreak(false), + ContainsUnwrappedBuilder(false), AlignColons(true), + ObjCSelectorNameFound(false), HasMultipleNestedBlocks(false), + NestedBlockInlined(false), IsInsideObjCArrayLiteral(false), + IsCSharpGenericTypeConstraint(false), IsChainedConditional(false), + IsWrappedConditional(false), UnindentOperator(false) {} /// \brief The token opening this parenthesis level, or nullptr if this level /// is opened by fake parenthesis. @@ -277,6 +277,13 @@ struct ParenState { /// was a newline after the beginning left brace. bool BreakBeforeClosingBrace : 1; + /// Whether a newline needs to be inserted before the block's closing + /// paren. + /// + /// We only want to insert a newline before the closing paren if there also + /// was a newline after the beginning left paren. + bool BreakBeforeClosingParen : 1; + /// Avoid bin packing, i.e. multiple parameters/elements on multiple /// lines, in this context. bool AvoidBinPacking : 1; @@ -362,6 +369,8 @@ struct ParenState { return IsAligned; if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace) return BreakBeforeClosingBrace; + if (BreakBeforeClosingParen != Other.BreakBeforeClosingParen) + return BreakBeforeClosingParen; if (QuestionColumn != Other.QuestionColumn) return QuestionColumn < Other.QuestionColumn; if (AvoidBinPacking != Other.AvoidBinPacking) diff --git contrib/llvm-project/clang/lib/Format/DefinitionBlockSeparator.cpp contrib/llvm-project/clang/lib/Format/DefinitionBlockSeparator.cpp new file mode 100644 index 000000000000..827564357f78 --- /dev/null +++ contrib/llvm-project/clang/lib/Format/DefinitionBlockSeparator.cpp @@ -0,0 +1,236 @@ +//===--- DefinitionBlockSeparator.cpp ---------------------------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file implements DefinitionBlockSeparator, a TokenAnalyzer that inserts +/// or removes empty lines separating definition blocks like classes, structs, +/// functions, enums, and namespaces in between. +/// +//===----------------------------------------------------------------------===// + +#include "DefinitionBlockSeparator.h" +#include "llvm/Support/Debug.h" +#define DEBUG_TYPE "definition-block-separator" + +namespace clang { +namespace format { +std::pair<tooling::Replacements, unsigned> DefinitionBlockSeparator::analyze( + TokenAnnotator &Annotator, SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, + FormatTokenLexer &Tokens) { + assert(Style.SeparateDefinitionBlocks != FormatStyle::SDS_Leave); + AffectedRangeMgr.computeAffectedLines(AnnotatedLines); + tooling::Replacements Result; + separateBlocks(AnnotatedLines, Result, Tokens); + return {Result, 0}; +} + +void DefinitionBlockSeparator::separateBlocks( + SmallVectorImpl<AnnotatedLine *> &Lines, tooling::Replacements &Result, + FormatTokenLexer &Tokens) { + const bool IsNeverStyle = + Style.SeparateDefinitionBlocks == FormatStyle::SDS_Never; + const AdditionalKeywords &ExtraKeywords = Tokens.getKeywords(); + auto LikelyDefinition = [this, ExtraKeywords](const AnnotatedLine *Line, + bool ExcludeEnum = false) { + if ((Line->MightBeFunctionDecl && Line->mightBeFunctionDefinition()) || + Line->startsWithNamespace()) + return true; + FormatToken *CurrentToken = Line->First; + while (CurrentToken) { + if (CurrentToken->isOneOf(tok::kw_class, tok::kw_struct) || + (Style.isJavaScript() && CurrentToken->is(ExtraKeywords.kw_function))) + return true; + if (!ExcludeEnum && CurrentToken->is(tok::kw_enum)) + return true; + CurrentToken = CurrentToken->Next; + } + return false; + }; + unsigned NewlineCount = + (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always ? 1 : 0) + 1; + WhitespaceManager Whitespaces( + Env.getSourceManager(), Style, + Style.DeriveLineEnding + ? WhitespaceManager::inputUsesCRLF( + Env.getSourceManager().getBufferData(Env.getFileID()), + Style.UseCRLF) + : Style.UseCRLF); + for (unsigned I = 0; I < Lines.size(); ++I) { + const auto &CurrentLine = Lines[I]; + if (CurrentLine->InPPDirective) + continue; + FormatToken *TargetToken = nullptr; + AnnotatedLine *TargetLine; + auto OpeningLineIndex = CurrentLine->MatchingOpeningBlockLineIndex; + AnnotatedLine *OpeningLine = nullptr; + const auto IsAccessSpecifierToken = [](const FormatToken *Token) { + return Token->isAccessSpecifier() || Token->isObjCAccessSpecifier(); + }; + const auto InsertReplacement = [&](const int NewlineToInsert) { + assert(TargetLine); + assert(TargetToken); + + // Do not handle EOF newlines. + if (TargetToken->is(tok::eof)) + return; + if (IsAccessSpecifierToken(TargetToken) || + (OpeningLineIndex > 0 && + IsAccessSpecifierToken(Lines[OpeningLineIndex - 1]->First))) + return; + if (!TargetLine->Affected) + return; + Whitespaces.replaceWhitespace(*TargetToken, NewlineToInsert, + TargetToken->OriginalColumn, + TargetToken->OriginalColumn); + }; + const auto IsPPConditional = [&](const size_t LineIndex) { + const auto &Line = Lines[LineIndex]; + return Line->First->is(tok::hash) && Line->First->Next && + Line->First->Next->isOneOf(tok::pp_if, tok::pp_ifdef, tok::pp_else, + tok::pp_ifndef, tok::pp_elifndef, + tok::pp_elifdef, tok::pp_elif, + tok::pp_endif); + }; + const auto FollowingOtherOpening = [&]() { + return OpeningLineIndex == 0 || + Lines[OpeningLineIndex - 1]->Last->opensScope() || + IsPPConditional(OpeningLineIndex - 1); + }; + const auto HasEnumOnLine = [&]() { + FormatToken *CurrentToken = CurrentLine->First; + bool FoundEnumKeyword = false; + while (CurrentToken) { + if (CurrentToken->is(tok::kw_enum)) + FoundEnumKeyword = true; + else if (FoundEnumKeyword && CurrentToken->is(tok::l_brace)) + return true; + CurrentToken = CurrentToken->Next; + } + return FoundEnumKeyword && I + 1 < Lines.size() && + Lines[I + 1]->First->is(tok::l_brace); + }; + + bool IsDefBlock = false; + const auto MayPrecedeDefinition = [&](const int Direction = -1) { + assert(Direction >= -1); + assert(Direction <= 1); + const size_t OperateIndex = OpeningLineIndex + Direction; + assert(OperateIndex < Lines.size()); + const auto &OperateLine = Lines[OperateIndex]; + if (LikelyDefinition(OperateLine)) + return false; + + if (OperateLine->First->is(tok::comment)) + return true; + + // A single line identifier that is not in the last line. + if (OperateLine->First->is(tok::identifier) && + OperateLine->First == OperateLine->Last && + OperateIndex + 1 < Lines.size()) { + // UnwrappedLineParser's recognition of free-standing macro like + // Q_OBJECT may also recognize some uppercased type names that may be + // used as return type as that kind of macros, which is a bit hard to + // distinguish one from another purely from token patterns. Here, we + // try not to add new lines below those identifiers. + AnnotatedLine *NextLine = Lines[OperateIndex + 1]; + if (NextLine->MightBeFunctionDecl && + NextLine->mightBeFunctionDefinition() && + NextLine->First->NewlinesBefore == 1 && + OperateLine->First->is(TT_FunctionLikeOrFreestandingMacro)) + return true; + } + + if ((Style.isCSharp() && OperateLine->First->is(TT_AttributeSquare))) + return true; + return false; + }; + + if (HasEnumOnLine() && + !LikelyDefinition(CurrentLine, /*ExcludeEnum=*/true)) { + // We have no scope opening/closing information for enum. + IsDefBlock = true; + OpeningLineIndex = I; + while (OpeningLineIndex > 0 && MayPrecedeDefinition()) + --OpeningLineIndex; + OpeningLine = Lines[OpeningLineIndex]; + TargetLine = OpeningLine; + TargetToken = TargetLine->First; + if (!FollowingOtherOpening()) + InsertReplacement(NewlineCount); + else if (IsNeverStyle) + InsertReplacement(OpeningLineIndex != 0); + TargetLine = CurrentLine; + TargetToken = TargetLine->First; + while (TargetToken && !TargetToken->is(tok::r_brace)) + TargetToken = TargetToken->Next; + if (!TargetToken) { + while (I < Lines.size() && !Lines[I]->First->is(tok::r_brace)) + ++I; + } + } else if (CurrentLine->First->closesScope()) { + if (OpeningLineIndex > Lines.size()) + continue; + // Handling the case that opening brace has its own line, with checking + // whether the last line already had an opening brace to guard against + // misrecognition. + if (OpeningLineIndex > 0 && + Lines[OpeningLineIndex]->First->is(tok::l_brace) && + Lines[OpeningLineIndex - 1]->Last->isNot(tok::l_brace)) + --OpeningLineIndex; + OpeningLine = Lines[OpeningLineIndex]; + // Closing a function definition. + if (LikelyDefinition(OpeningLine)) { + IsDefBlock = true; + while (OpeningLineIndex > 0 && MayPrecedeDefinition()) + --OpeningLineIndex; + OpeningLine = Lines[OpeningLineIndex]; + TargetLine = OpeningLine; + TargetToken = TargetLine->First; + if (!FollowingOtherOpening()) { + // Avoid duplicated replacement. + if (TargetToken->isNot(tok::l_brace)) + InsertReplacement(NewlineCount); + } else if (IsNeverStyle) + InsertReplacement(OpeningLineIndex != 0); + } + } + + // Not the last token. + if (IsDefBlock && I + 1 < Lines.size()) { + OpeningLineIndex = I + 1; + TargetLine = Lines[OpeningLineIndex]; + TargetToken = TargetLine->First; + + // No empty line for continuously closing scopes. The token will be + // handled in another case if the line following is opening a + // definition. + if (!TargetToken->closesScope() && !IsPPConditional(OpeningLineIndex)) { + // Check whether current line may precede a definition line. + while (OpeningLineIndex + 1 < Lines.size() && + MayPrecedeDefinition(/*Direction=*/0)) + ++OpeningLineIndex; + TargetLine = Lines[OpeningLineIndex]; + if (!LikelyDefinition(TargetLine)) { + OpeningLineIndex = I + 1; + TargetLine = Lines[I + 1]; + TargetToken = TargetLine->First; + InsertReplacement(NewlineCount); + } + } else if (IsNeverStyle) + InsertReplacement(/*NewlineToInsert=*/1); + } + } + for (const auto &R : Whitespaces.generateReplacements()) + // The add method returns an Error instance which simulates program exit + // code through overloading boolean operator, thus false here indicates + // success. + if (Result.add(R)) + return; +} +} // namespace format +} // namespace clang diff --git contrib/llvm-project/clang/lib/Format/DefinitionBlockSeparator.h contrib/llvm-project/clang/lib/Format/DefinitionBlockSeparator.h new file mode 100644 index 000000000000..31c0f34d6e19 --- /dev/null +++ contrib/llvm-project/clang/lib/Format/DefinitionBlockSeparator.h @@ -0,0 +1,41 @@ +//===--- DefinitionBlockSeparator.h -----------------------------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file declares DefinitionBlockSeparator, a TokenAnalyzer that inserts or +/// removes empty lines separating definition blocks like classes, structs, +/// functions, enums, and namespaces in between. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_FORMAT_DEFINITIONBLOCKSEPARATOR_H +#define LLVM_CLANG_LIB_FORMAT_DEFINITIONBLOCKSEPARATOR_H + +#include "TokenAnalyzer.h" +#include "WhitespaceManager.h" + +namespace clang { +namespace format { +class DefinitionBlockSeparator : public TokenAnalyzer { +public: + DefinitionBlockSeparator(const Environment &Env, const FormatStyle &Style) + : TokenAnalyzer(Env, Style) {} + + std::pair<tooling::Replacements, unsigned> + analyze(TokenAnnotator &Annotator, + SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, + FormatTokenLexer &Tokens) override; + +private: + void separateBlocks(SmallVectorImpl<AnnotatedLine *> &Lines, + tooling::Replacements &Result, FormatTokenLexer &Tokens); +}; +} // namespace format +} // namespace clang + +#endif diff --git contrib/llvm-project/clang/lib/Format/Format.cpp contrib/llvm-project/clang/lib/Format/Format.cpp index be01daa38929..04e2915e3af6 100644 --- contrib/llvm-project/clang/lib/Format/Format.cpp +++ contrib/llvm-project/clang/lib/Format/Format.cpp @@ -16,6 +16,7 @@ #include "AffectedRangeManager.h" #include "BreakableToken.h" #include "ContinuationIndenter.h" +#include "DefinitionBlockSeparator.h" #include "FormatInternal.h" #include "FormatTokenLexer.h" #include "NamespaceEndCommentsFixer.h" @@ -383,6 +384,7 @@ template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> { IO.enumCase(Value, "Align", FormatStyle::BAS_Align); IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign); IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak); + IO.enumCase(Value, "BlockIndent", FormatStyle::BAS_BlockIndent); // For backward compatibility. IO.enumCase(Value, "true", FormatStyle::BAS_Align); @@ -429,6 +431,15 @@ template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> { } }; +template <> +struct ScalarEnumerationTraits<FormatStyle::SeparateDefinitionStyle> { + static void enumeration(IO &IO, FormatStyle::SeparateDefinitionStyle &Value) { + IO.enumCase(Value, "Leave", FormatStyle::SDS_Leave); + IO.enumCase(Value, "Always", FormatStyle::SDS_Always); + IO.enumCase(Value, "Never", FormatStyle::SDS_Never); + } +}; + template <> struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> { static void @@ -756,6 +767,8 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment); IO.mapOptional("PenaltyBreakFirstLessLess", Style.PenaltyBreakFirstLessLess); + IO.mapOptional("PenaltyBreakOpenParenthesis", + Style.PenaltyBreakOpenParenthesis); IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString); IO.mapOptional("PenaltyBreakTemplateDeclaration", Style.PenaltyBreakTemplateDeclaration); @@ -769,6 +782,8 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("RawStringFormats", Style.RawStringFormats); IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment); IO.mapOptional("ReflowComments", Style.ReflowComments); + IO.mapOptional("RemoveBracesLLVM", Style.RemoveBracesLLVM); + IO.mapOptional("SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks); IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines); IO.mapOptional("SortIncludes", Style.SortIncludes); IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport); @@ -855,6 +870,7 @@ template <> struct MappingTraits<FormatStyle::SpaceBeforeParensCustom> { IO.mapOptional("AfterFunctionDeclarationName", Spacing.AfterFunctionDeclarationName); IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros); + IO.mapOptional("AfterOverloadedOperator", Spacing.AfterOverloadedOperator); IO.mapOptional("BeforeNonEmptyParentheses", Spacing.BeforeNonEmptyParentheses); } @@ -1193,12 +1209,14 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.ObjCSpaceBeforeProtocolList = true; LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer; + LLVMStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Leave; LLVMStyle.ShortNamespaceLines = 1; LLVMStyle.SpacesBeforeTrailingComments = 1; LLVMStyle.Standard = FormatStyle::LS_Latest; LLVMStyle.UseCRLF = false; LLVMStyle.UseTab = FormatStyle::UT_Never; LLVMStyle.ReflowComments = true; + LLVMStyle.RemoveBracesLLVM = false; LLVMStyle.SpacesInParentheses = false; LLVMStyle.SpacesInSquareBrackets = false; LLVMStyle.SpaceInEmptyBlock = false; @@ -1232,6 +1250,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.PenaltyExcessCharacter = 1000000; LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60; LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19; + LLVMStyle.PenaltyBreakOpenParenthesis = 0; LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational; LLVMStyle.PenaltyIndentedWhitespace = 0; @@ -1732,6 +1751,45 @@ FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const { namespace { +class BracesRemover : public TokenAnalyzer { +public: + BracesRemover(const Environment &Env, const FormatStyle &Style) + : TokenAnalyzer(Env, Style) {} + + std::pair<tooling::Replacements, unsigned> + analyze(TokenAnnotator &Annotator, + SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, + FormatTokenLexer &Tokens) override { + AffectedRangeMgr.computeAffectedLines(AnnotatedLines); + tooling::Replacements Result; + removeBraces(AnnotatedLines, Result); + return {Result, 0}; + } + +private: + // Remove optional braces. + void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines, + tooling::Replacements &Result) { + const auto &SourceMgr = Env.getSourceManager(); + for (AnnotatedLine *Line : Lines) { + removeBraces(Line->Children, Result); + if (!Line->Affected) + continue; + for (FormatToken *Token = Line->First; Token; Token = Token->Next) { + if (!Token->Optional) + continue; + assert(Token->isOneOf(tok::l_brace, tok::r_brace)); + const auto Start = Token == Line->Last + ? Token->WhitespaceRange.getBegin() + : Token->Tok.getLocation(); + const auto Range = + CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc()); + cantFail(Result.add(tooling::Replacement(SourceMgr, Range, ""))); + } + } + } +}; + class JavaScriptRequoter : public TokenAnalyzer { public: JavaScriptRequoter(const Environment &Env, const FormatStyle &Style) @@ -1840,7 +1898,7 @@ public: WhitespaceManager Whitespaces( Env.getSourceManager(), Style, Style.DeriveLineEnding - ? inputUsesCRLF( + ? WhitespaceManager::inputUsesCRLF( Env.getSourceManager().getBufferData(Env.getFileID()), Style.UseCRLF) : Style.UseCRLF); @@ -1864,19 +1922,13 @@ public: } private: - static bool inputUsesCRLF(StringRef Text, bool DefaultToCRLF) { - size_t LF = Text.count('\n'); - size_t CR = Text.count('\r') * 2; - return LF == CR ? DefaultToCRLF : CR > LF; - } - bool hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) { for (const AnnotatedLine *Line : Lines) { if (hasCpp03IncompatibleFormat(Line->Children)) return true; for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) { - if (Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd()) { + if (!Tok->hasWhitespaceBefore()) { if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener)) return true; if (Tok->is(TT_TemplateCloser) && @@ -1895,10 +1947,8 @@ private: for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) { if (!Tok->is(TT_PointerOrReference)) continue; - bool SpaceBefore = - Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd(); - bool SpaceAfter = Tok->Next->WhitespaceRange.getBegin() != - Tok->Next->WhitespaceRange.getEnd(); + bool SpaceBefore = Tok->hasWhitespaceBefore(); + bool SpaceAfter = Tok->Next->hasWhitespaceBefore(); if (SpaceBefore && !SpaceAfter) ++AlignmentDiff; if (!SpaceBefore && SpaceAfter) @@ -2204,7 +2254,7 @@ private: unsigned St = Idx, End = Idx; while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1]) { - End++; + ++End; } auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(), Tokens[End]->Tok.getEndLoc()); @@ -2440,7 +2490,7 @@ std::string replaceCRLF(const std::string &Code) { do { Pos = Code.find("\r\n", LastPos); if (Pos == LastPos) { - LastPos++; + ++LastPos; continue; } if (Pos == std::string::npos) { @@ -2586,8 +2636,9 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code, bool MainIncludeFound = false; bool FormattingOff = false; + // '[' must be the first and '-' the last character inside [...]. llvm::Regex RawStringRegex( - "R\"(([\\[A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'\\-]|])*)\\("); + "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\("); SmallVector<StringRef, 2> RawStringMatches; std::string RawStringTermination = ")\""; @@ -3038,6 +3089,11 @@ reformat(const FormatStyle &Style, StringRef Code, }); } + if (Style.isCpp() && Style.RemoveBracesLLVM) + Passes.emplace_back([&](const Environment &Env) { + return BracesRemover(Env, Expanded).process(); + }); + if (Style.Language == FormatStyle::LK_Cpp) { if (Style.FixNamespaceComments) Passes.emplace_back([&](const Environment &Env) { @@ -3050,6 +3106,11 @@ reformat(const FormatStyle &Style, StringRef Code, }); } + if (Style.SeparateDefinitionBlocks != FormatStyle::SDS_Leave) + Passes.emplace_back([&](const Environment &Env) { + return DefinitionBlockSeparator(Env, Expanded).process(); + }); + if (Style.isJavaScript() && Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) Passes.emplace_back([&](const Environment &Env) { return JavaScriptRequoter(Env, Expanded).process(); @@ -3138,6 +3199,16 @@ tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, return NamespaceEndCommentsFixer(*Env, Style).process().first; } +tooling::Replacements separateDefinitionBlocks(const FormatStyle &Style, + StringRef Code, + ArrayRef<tooling::Range> Ranges, + StringRef FileName) { + auto Env = Environment::make(Code, FileName, Ranges); + if (!Env) + return {}; + return DefinitionBlockSeparator(*Env, Style).process().first; +} + tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, StringRef Code, ArrayRef<tooling::Range> Ranges, @@ -3181,6 +3252,8 @@ const char *StyleOptionHelpDescription = ".clang-format file located in one of the parent\n" "directories of the source file (or current\n" "directory for stdin).\n" + "Use -style=file:<format_file_path> to explicitly specify" + "the configuration file.\n" "Use -style=\"{key: value, ...}\" to set specific\n" "parameters, e.g.:\n" " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\""; @@ -3233,6 +3306,18 @@ const char *DefaultFormatStyle = "file"; const char *DefaultFallbackStyle = "LLVM"; +llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> +loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS, + FormatStyle *Style, bool AllowUnknownOptions) { + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = + FS->getBufferForFile(ConfigFile.str()); + if (auto EC = Text.getError()) + return EC; + if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions)) + return EC; + return Text; +} + llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, StringRef FallbackStyleName, StringRef Code, llvm::vfs::FileSystem *FS, @@ -3263,6 +3348,28 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, return Style; } + // User provided clang-format file using -style=file:path/to/format/file. + if (!Style.InheritsParentConfig && + StyleName.startswith_insensitive("file:")) { + auto ConfigFile = StyleName.substr(5); + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = + loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions); + if (auto EC = Text.getError()) + return make_string_error("Error reading " + ConfigFile + ": " + + EC.message()); + + LLVM_DEBUG(llvm::dbgs() + << "Using configuration file " << ConfigFile << "\n"); + + if (!Style.InheritsParentConfig) + return Style; + + // Search for parent configs starting from the parent directory of + // ConfigFile. + FileName = ConfigFile; + ChildFormatTextToApply.emplace_back(std::move(*Text)); + } + // If the style inherits the parent configuration it is a command line // configuration, which wants to inherit, so we have to skip the check of the // StyleName. @@ -3288,6 +3395,16 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {}; + auto applyChildFormatTexts = [&](FormatStyle *Style) { + for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) { + auto EC = parseConfiguration(*MemBuf, Style, AllowUnknownOptions, + dropDiagnosticHandler); + // It was already correctly parsed. + assert(!EC); + static_cast<void>(EC); + } + }; + for (StringRef Directory = Path; !Directory.empty(); Directory = llvm::sys::path::parent_path(Directory)) { @@ -3308,19 +3425,16 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, if (Status && (Status->getType() == llvm::sys::fs::file_type::regular_file)) { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = - FS->getBufferForFile(ConfigFile.str()); - if (std::error_code EC = Text.getError()) - return make_string_error(EC.message()); - if (std::error_code ec = - parseConfiguration(*Text.get(), &Style, AllowUnknownOptions)) { - if (ec == ParseError::Unsuitable) { + loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions); + if (auto EC = Text.getError()) { + if (EC == ParseError::Unsuitable) { if (!UnsuitableConfigFiles.empty()) UnsuitableConfigFiles.append(", "); UnsuitableConfigFiles.append(ConfigFile); continue; } return make_string_error("Error reading " + ConfigFile + ": " + - ec.message()); + EC.message()); } LLVM_DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n"); @@ -3330,14 +3444,7 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, return Style; LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n"); - - for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) { - auto Ec = parseConfiguration(*MemBuf, &Style, AllowUnknownOptions, - dropDiagnosticHandler); - // It was already correctly parsed. - assert(!Ec); - static_cast<void>(Ec); - } + applyChildFormatTexts(&Style); return Style; } @@ -3363,17 +3470,9 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, UnsuitableConfigFiles); if (!ChildFormatTextToApply.empty()) { - assert(ChildFormatTextToApply.size() == 1); - LLVM_DEBUG(llvm::dbgs() - << "Applying child configuration on fallback style\n"); - - auto Ec = - parseConfiguration(*ChildFormatTextToApply.front(), &FallbackStyle, - AllowUnknownOptions, dropDiagnosticHandler); - // It was already correctly parsed. - assert(!Ec); - static_cast<void>(Ec); + << "Applying child configurations on fallback style\n"); + applyChildFormatTexts(&FallbackStyle); } return FallbackStyle; diff --git contrib/llvm-project/clang/lib/Format/FormatToken.cpp contrib/llvm-project/clang/lib/Format/FormatToken.cpp index 57f8a5a45cbb..59d6f29bb54d 100644 --- contrib/llvm-project/clang/lib/Format/FormatToken.cpp +++ contrib/llvm-project/clang/lib/Format/FormatToken.cpp @@ -189,6 +189,7 @@ void CommaSeparatedList::precomputeFormattingInfos(const FormatToken *Token) { bool HasSeparatingComment = false; for (unsigned i = 0, e = Commas.size() + 1; i != e; ++i) { + assert(ItemBegin); // Skip comments on their own line. while (ItemBegin->HasUnescapedNewline && ItemBegin->isTrailingComment()) { ItemBegin = ItemBegin->Next; @@ -296,14 +297,11 @@ void CommaSeparatedList::precomputeFormattingInfos(const FormatToken *Token) { const CommaSeparatedList::ColumnFormat * CommaSeparatedList::getColumnFormat(unsigned RemainingCharacters) const { const ColumnFormat *BestFormat = nullptr; - for (SmallVector<ColumnFormat, 4>::const_reverse_iterator - I = Formats.rbegin(), - E = Formats.rend(); - I != E; ++I) { - if (I->TotalWidth <= RemainingCharacters || I->Columns == 1) { - if (BestFormat && I->LineCount > BestFormat->LineCount) + for (const ColumnFormat &Format : llvm::reverse(Formats)) { + if (Format.TotalWidth <= RemainingCharacters || Format.Columns == 1) { + if (BestFormat && Format.LineCount > BestFormat->LineCount) break; - BestFormat = &*I; + BestFormat = &Format; } } return BestFormat; diff --git contrib/llvm-project/clang/lib/Format/FormatToken.h contrib/llvm-project/clang/lib/Format/FormatToken.h index d410ede32240..a64329802ee3 100644 --- contrib/llvm-project/clang/lib/Format/FormatToken.h +++ contrib/llvm-project/clang/lib/Format/FormatToken.h @@ -51,6 +51,7 @@ namespace format { TYPE(FunctionAnnotationRParen) \ TYPE(FunctionDeclarationName) \ TYPE(FunctionLBrace) \ + TYPE(FunctionLikeOrFreestandingMacro) \ TYPE(FunctionTypeLParen) \ TYPE(IfMacro) \ TYPE(ImplicitStringLiteral) \ @@ -95,6 +96,7 @@ namespace format { TYPE(PointerOrReference) \ TYPE(PureVirtualSpecifier) \ TYPE(RangeBasedForLoopColon) \ + TYPE(RecordLBrace) \ TYPE(RegexLiteral) \ TYPE(SelectorName) \ TYPE(StartOfName) \ @@ -442,6 +444,9 @@ public: /// This starts an array initializer. bool IsArrayInitializer = false; + /// Is optional and can be removed. + bool Optional = false; + /// If this token starts a block, this contains all the unwrapped lines /// in it. SmallVector<AnnotatedLine *, 1> Children; @@ -634,6 +639,12 @@ public: return WhitespaceRange.getEnd(); } + /// Returns \c true if the range of whitespace immediately preceding the \c + /// Token is not empty. + bool hasWhitespaceBefore() const { + return WhitespaceRange.getBegin() != WhitespaceRange.getEnd(); + } + prec::Level getPrecedence() const { return getBinOpPrecedence(Tok.getKind(), /*GreaterThanIsOperator=*/true, /*CPlusPlus11=*/true); diff --git contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp index 7736a7042f86..c9166f4b17aa 100644 --- contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp +++ contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp @@ -429,18 +429,21 @@ bool FormatTokenLexer::tryMergeLessLess() { if (Tokens.size() < 3) return false; - bool FourthTokenIsLess = false; - if (Tokens.size() > 3) - FourthTokenIsLess = (Tokens.end() - 4)[0]->is(tok::less); - auto First = Tokens.end() - 3; - if (First[2]->is(tok::less) || First[1]->isNot(tok::less) || - First[0]->isNot(tok::less) || FourthTokenIsLess) + if (First[0]->isNot(tok::less) || First[1]->isNot(tok::less)) return false; // Only merge if there currently is no whitespace between the two "<". - if (First[1]->WhitespaceRange.getBegin() != - First[1]->WhitespaceRange.getEnd()) + if (First[1]->hasWhitespaceBefore()) + return false; + + auto X = Tokens.size() > 3 ? First[-1] : nullptr; + auto Y = First[2]; + if ((X && X->is(tok::less)) || Y->is(tok::less)) + return false; + + // Do not remove a whitespace between the two "<" e.g. "operator< <>". + if (X && X->is(tok::kw_operator) && Y->is(tok::greater)) return false; First[0]->Tok.setKind(tok::lessless); @@ -461,8 +464,7 @@ bool FormatTokenLexer::tryMergeTokens(ArrayRef<tok::TokenKind> Kinds, return false; unsigned AddLength = 0; for (unsigned i = 1; i < Kinds.size(); ++i) { - if (!First[i]->is(Kinds[i]) || First[i]->WhitespaceRange.getBegin() != - First[i]->WhitespaceRange.getEnd()) + if (!First[i]->is(Kinds[i]) || First[i]->hasWhitespaceBefore()) return false; AddLength += First[i]->TokenText.size(); } diff --git contrib/llvm-project/clang/lib/Format/NamespaceEndCommentsFixer.cpp contrib/llvm-project/clang/lib/Format/NamespaceEndCommentsFixer.cpp index 38ab5b9df76d..0c34c6126c21 100644 --- contrib/llvm-project/clang/lib/Format/NamespaceEndCommentsFixer.cpp +++ contrib/llvm-project/clang/lib/Format/NamespaceEndCommentsFixer.cpp @@ -28,7 +28,7 @@ std::string computeName(const FormatToken *NamespaceTok) { assert(NamespaceTok && NamespaceTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) && "expecting a namespace token"); - std::string name = ""; + std::string name; const FormatToken *Tok = NamespaceTok->getNextNonComment(); if (NamespaceTok->is(TT_NamespaceMacro)) { // Collects all the non-comment tokens between opening parenthesis @@ -224,7 +224,7 @@ std::pair<tooling::Replacements, unsigned> NamespaceEndCommentsFixer::analyze( return {Fixes, 0}; } - std::string AllNamespaceNames = ""; + std::string AllNamespaceNames; size_t StartLineIndex = SIZE_MAX; StringRef NamespaceTokenText; unsigned int CompactedNamespacesCount = 0; @@ -260,8 +260,9 @@ std::pair<tooling::Replacements, unsigned> NamespaceEndCommentsFixer::analyze( // remove end comment, it will be merged in next one updateEndComment(EndCommentPrevTok, std::string(), SourceMgr, &Fixes); } - CompactedNamespacesCount++; - AllNamespaceNames = "::" + NamespaceName + AllNamespaceNames; + ++CompactedNamespacesCount; + if (!NamespaceName.empty()) + AllNamespaceNames = "::" + NamespaceName + AllNamespaceNames; continue; } NamespaceName += AllNamespaceNames; diff --git contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.cpp contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.cpp index 5a89225c7fc8..b3a4684bead1 100644 --- contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.cpp +++ contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -88,11 +88,11 @@ std::pair<tooling::Replacements, unsigned> QualifierAlignmentFixer::analyze( // Don't make replacements that replace nothing. tooling::Replacements NonNoOpFixes; - for (auto I = Fixes.begin(), E = Fixes.end(); I != E; ++I) { - StringRef OriginalCode = Code.substr(I->getOffset(), I->getLength()); + for (const tooling::Replacement &Fix : Fixes) { + StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength()); - if (!OriginalCode.equals(I->getReplacementText())) { - auto Err = NonNoOpFixes.add(*I); + if (!OriginalCode.equals(Fix.getReplacementText())) { + auto Err = NonNoOpFixes.add(Fix); if (Err) llvm::errs() << "Error adding replacements : " << llvm::toString(std::move(Err)) << "\n"; @@ -204,9 +204,9 @@ static void rotateTokens(const SourceManager &SourceMgr, replaceToken(SourceMgr, Fixes, Range, NewText); } -FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( +const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( const SourceManager &SourceMgr, const AdditionalKeywords &Keywords, - tooling::Replacements &Fixes, FormatToken *Tok, + tooling::Replacements &Fixes, const FormatToken *Tok, const std::string &Qualifier, tok::TokenKind QualifierType) { // We only need to think about streams that begin with a qualifier. if (!Tok->is(QualifierType)) @@ -261,10 +261,8 @@ FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( // Move to the end of any template class members e.g. // `Foo<int>::iterator`. if (Next && Next->startsSequence(TT_TemplateCloser, tok::coloncolon, - tok::identifier)) { - Next = Next->Next->Next; + tok::identifier)) return Tok; - } assert(Next && "Missing template opener"); Next = Next->Next; } @@ -281,16 +279,16 @@ FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( return Tok; } -FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft( +const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft( const SourceManager &SourceMgr, const AdditionalKeywords &Keywords, - tooling::Replacements &Fixes, FormatToken *Tok, + tooling::Replacements &Fixes, const FormatToken *Tok, const std::string &Qualifier, tok::TokenKind QualifierType) { // if Tok is an identifier and possibly a macro then don't convert. if (LeftRightQualifierAlignmentFixer::isPossibleMacro(Tok)) return Tok; - FormatToken *Qual = Tok; - FormatToken *LastQual = Qual; + const FormatToken *Qual = Tok; + const FormatToken *LastQual = Qual; while (Qual && isQualifierOrType(Qual, ConfiguredQualifierTokens)) { LastQual = Qual; Qual = Qual->Next; @@ -326,7 +324,7 @@ FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft( Tok->Previous->isOneOf(tok::star, tok::ampamp, tok::amp)) { return Tok; } - FormatToken *Next = Tok->Next; + const FormatToken *Next = Tok->Next; // The case `std::Foo<T> const` -> `const std::Foo<T> &&` while (Next && Next->isOneOf(tok::identifier, tok::coloncolon)) Next = Next->Next; @@ -334,6 +332,8 @@ FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft( Next->Previous->startsSequence(tok::identifier, TT_TemplateOpener)) { // Read from to the end of the TemplateOpener to // TemplateCloser const ArrayRef<int> a; const ArrayRef<int> &a; + if (Next->is(tok::comment) && Next->getNextNonComment()) + Next = Next->getNextNonComment(); assert(Next->MatchingParen && "Missing template closer"); Next = Next->MatchingParen->Next; @@ -394,11 +394,12 @@ LeftRightQualifierAlignmentFixer::analyze( tok::TokenKind QualifierToken = getTokenFromQualifier(Qualifier); assert(QualifierToken != tok::identifier && "Unrecognised Qualifier"); - for (size_t I = 0, E = AnnotatedLines.size(); I != E; ++I) { - FormatToken *First = AnnotatedLines[I]->First; - const auto *Last = AnnotatedLines[I]->Last; + for (AnnotatedLine *Line : AnnotatedLines) { + FormatToken *First = Line->First; + const auto *Last = Line->Last; - for (auto *Tok = First; Tok && Tok != Last && Tok->Next; Tok = Tok->Next) { + for (const auto *Tok = First; Tok && Tok != Last && Tok->Next; + Tok = Tok->Next) { if (Tok->is(tok::comment)) continue; if (RightAlign) diff --git contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.h contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.h index 7abd25687564..30ef96b8b0a7 100644 --- contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.h +++ contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.h @@ -72,17 +72,19 @@ public: static tok::TokenKind getTokenFromQualifier(const std::string &Qualifier); - FormatToken *analyzeRight(const SourceManager &SourceMgr, - const AdditionalKeywords &Keywords, - tooling::Replacements &Fixes, FormatToken *Tok, - const std::string &Qualifier, - tok::TokenKind QualifierType); - - FormatToken *analyzeLeft(const SourceManager &SourceMgr, - const AdditionalKeywords &Keywords, - tooling::Replacements &Fixes, FormatToken *Tok, - const std::string &Qualifier, - tok::TokenKind QualifierType); + const FormatToken *analyzeRight(const SourceManager &SourceMgr, + const AdditionalKeywords &Keywords, + tooling::Replacements &Fixes, + const FormatToken *Tok, + const std::string &Qualifier, + tok::TokenKind QualifierType); + + const FormatToken *analyzeLeft(const SourceManager &SourceMgr, + const AdditionalKeywords &Keywords, + tooling::Replacements &Fixes, + const FormatToken *Tok, + const std::string &Qualifier, + tok::TokenKind QualifierType); // is the Token a simple or qualifier type static bool isQualifierOrType(const FormatToken *Tok, diff --git contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp index 77dc0d683e5f..e4107525a7ff 100644 --- contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp +++ contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp @@ -78,6 +78,7 @@ struct JsModuleReference { ABSOLUTE, // from 'something' RELATIVE_PARENT, // from '../*' RELATIVE, // from './*' + ALIAS, // import X = A.B; }; ReferenceCategory Category = ReferenceCategory::SIDE_EFFECT; // The URL imported, e.g. `import .. from 'url';`. Empty for `export {a, b};`. @@ -105,10 +106,12 @@ bool operator<(const JsModuleReference &LHS, const JsModuleReference &RHS) { return LHS.IsExport < RHS.IsExport; if (LHS.Category != RHS.Category) return LHS.Category < RHS.Category; - if (LHS.Category == JsModuleReference::ReferenceCategory::SIDE_EFFECT) - // Side effect imports might be ordering sensitive. Consider them equal so - // that they maintain their relative order in the stable sort below. - // This retains transitivity because LHS.Category == RHS.Category here. + if (LHS.Category == JsModuleReference::ReferenceCategory::SIDE_EFFECT || + LHS.Category == JsModuleReference::ReferenceCategory::ALIAS) + // Side effect imports and aliases might be ordering sensitive. Consider + // them equal so that they maintain their relative order in the stable sort + // below. This retains transitivity because LHS.Category == RHS.Category + // here. return false; // Empty URLs sort *last* (for export {...};). if (LHS.URL.empty() != RHS.URL.empty()) @@ -260,13 +263,13 @@ private: while (Start != References.end() && Start->FormattingOff) { // Skip over all imports w/ disabled formatting. ReferencesSorted.push_back(*Start); - Start++; + ++Start; } SmallVector<JsModuleReference, 16> SortChunk; while (Start != References.end() && !Start->FormattingOff) { // Skip over all imports w/ disabled formatting. SortChunk.push_back(*Start); - Start++; + ++Start; } llvm::stable_sort(SortChunk); mergeModuleReferences(SortChunk); @@ -338,10 +341,12 @@ private: // Stitch together the module reference start... Buffer += getSourceText(Reference.Range.getBegin(), Reference.SymbolsStart); // ... then the references in order ... - for (auto I = Symbols.begin(), E = Symbols.end(); I != E; ++I) { - if (I != Symbols.begin()) + if (!Symbols.empty()) { + Buffer += getSourceText(Symbols.front().Range); + for (const JsImportedSymbol &Symbol : llvm::drop_begin(Symbols)) { Buffer += ","; - Buffer += getSourceText(I->Range); + Buffer += getSourceText(Symbol.Range); + } } // ... followed by the module reference end. Buffer += getSourceText(Reference.SymbolsEnd, Reference.Range.getEnd()); @@ -359,6 +364,7 @@ private: bool AnyImportAffected = false; bool FormattingOff = false; for (auto *Line : AnnotatedLines) { + assert(Line->First); Current = Line->First; LineEnd = Line->Last; // clang-format comments toggle formatting on/off. @@ -395,6 +401,8 @@ private: JsModuleReference Reference; Reference.FormattingOff = FormattingOff; Reference.Range.setBegin(Start); + // References w/o a URL, e.g. export {A}, groups with RELATIVE. + Reference.Category = JsModuleReference::ReferenceCategory::RELATIVE; if (!parseModuleReference(Keywords, Reference)) { if (!FirstNonImportLine) FirstNonImportLine = Line; // if no comment before. @@ -410,9 +418,8 @@ private: << ", cat: " << Reference.Category << ", url: " << Reference.URL << ", prefix: " << Reference.Prefix; - for (size_t I = 0; I < Reference.Symbols.size(); ++I) - llvm::dbgs() << ", " << Reference.Symbols[I].Symbol << " as " - << Reference.Symbols[I].Alias; + for (const JsImportedSymbol &Symbol : Reference.Symbols) + llvm::dbgs() << ", " << Symbol.Symbol << " as " << Symbol.Alias; llvm::dbgs() << ", text: " << getSourceText(Reference.Range); llvm::dbgs() << "}\n"; }); @@ -461,9 +468,6 @@ private: Reference.Category = JsModuleReference::ReferenceCategory::RELATIVE; else Reference.Category = JsModuleReference::ReferenceCategory::ABSOLUTE; - } else { - // w/o URL groups with "empty". - Reference.Category = JsModuleReference::ReferenceCategory::RELATIVE; } return true; } @@ -499,6 +503,21 @@ private: nextToken(); if (Current->is(Keywords.kw_from)) return true; + // import X = A.B.C; + if (Current->is(tok::equal)) { + Reference.Category = JsModuleReference::ReferenceCategory::ALIAS; + nextToken(); + while (Current->is(tok::identifier)) { + nextToken(); + if (Current->is(tok::semi)) { + nextToken(); + return true; + } + if (!Current->is(tok::period)) + return false; + nextToken(); + } + } if (Current->isNot(tok::comma)) return false; nextToken(); // eat comma. diff --git contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp index d83e837ca134..d0754e0c1112 100644 --- contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp +++ contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp @@ -127,11 +127,8 @@ std::pair<tooling::Replacements, unsigned> TokenAnalyzer::process() { LLVM_DEBUG({ llvm::dbgs() << "Replacements for run " << Run << ":\n"; - for (tooling::Replacements::const_iterator I = RunResult.first.begin(), - E = RunResult.first.end(); - I != E; ++I) { - llvm::dbgs() << I->toString() << "\n"; - } + for (const tooling::Replacement &Fix : RunResult.first) + llvm::dbgs() << Fix.toString() << "\n"; }); for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { delete AnnotatedLines[i]; diff --git contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp index 505a7250572b..9d130dbb02eb 100644 --- contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp +++ contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp @@ -75,7 +75,7 @@ public: : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false), Keywords(Keywords) { Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false)); - resetTokenMetadata(CurrentToken); + resetTokenMetadata(); } private: @@ -780,6 +780,7 @@ private: unsigned CommaCount = 0; while (CurrentToken) { if (CurrentToken->is(tok::r_brace)) { + assert(Left->Optional == CurrentToken->Optional); Left->MatchingParen = CurrentToken; CurrentToken->MatchingParen = Left; if (Style.AlignArrayOfStructures != FormatStyle::AIAS_None) { @@ -1409,8 +1410,8 @@ private: Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren); } - void resetTokenMetadata(FormatToken *Token) { - if (!Token) + void resetTokenMetadata() { + if (!CurrentToken) return; // Reset token type in case we have already looked at it and then @@ -1422,7 +1423,8 @@ private: TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator, TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral, TT_UntouchableMacroFunc, TT_ConstraintJunctions, - TT_StatementAttributeLikeMacro)) + TT_StatementAttributeLikeMacro, TT_FunctionLikeOrFreestandingMacro, + TT_RecordLBrace)) CurrentToken->setType(TT_Unknown); CurrentToken->Role.reset(); CurrentToken->MatchingParen = nullptr; @@ -1431,15 +1433,16 @@ private: } void next() { - if (CurrentToken) { - CurrentToken->NestingLevel = Contexts.size() - 1; - CurrentToken->BindingStrength = Contexts.back().BindingStrength; - modifyContext(*CurrentToken); - determineTokenType(*CurrentToken); - CurrentToken = CurrentToken->Next; - } + if (!CurrentToken) + return; + + CurrentToken->NestingLevel = Contexts.size() - 1; + CurrentToken->BindingStrength = Contexts.back().BindingStrength; + modifyContext(*CurrentToken); + determineTokenType(*CurrentToken); + CurrentToken = CurrentToken->Next; - resetTokenMetadata(CurrentToken); + resetTokenMetadata(); } /// A struct to hold information valid in a specific context, e.g. @@ -1563,9 +1566,9 @@ private: int ParenLevel = 0; while (Current) { if (Current->is(tok::l_paren)) - ParenLevel++; + ++ParenLevel; if (Current->is(tok::r_paren)) - ParenLevel--; + --ParenLevel; if (ParenLevel < 1) break; Current = Current->Next; @@ -1589,9 +1592,9 @@ private: break; } if (TemplateCloser->is(tok::less)) - NestingLevel++; + ++NestingLevel; if (TemplateCloser->is(tok::greater)) - NestingLevel--; + --NestingLevel; if (NestingLevel < 1) break; TemplateCloser = TemplateCloser->Next; @@ -1882,15 +1885,23 @@ private: FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment(); if (LeftOfParens) { - // If there is a closing parenthesis left of the current parentheses, - // look past it as these might be chained casts. - if (LeftOfParens->is(tok::r_paren)) { + // If there is a closing parenthesis left of the current + // parentheses, look past it as these might be chained casts. + if (LeftOfParens->is(tok::r_paren) && + LeftOfParens->isNot(TT_CastRParen)) { if (!LeftOfParens->MatchingParen || !LeftOfParens->MatchingParen->Previous) return false; LeftOfParens = LeftOfParens->MatchingParen->Previous; } + // The Condition directly below this one will see the operator arguments + // as a (void *foo) cast. + // void operator delete(void *foo) ATTRIB; + if (LeftOfParens->Tok.getIdentifierInfo() && LeftOfParens->Previous && + LeftOfParens->Previous->is(tok::kw_operator)) + return false; + // If there is an identifier (or with a few exceptions a keyword) right // before the parentheses, this is unlikely to be a cast. if (LeftOfParens->Tok.getIdentifierInfo() && @@ -2343,9 +2354,10 @@ private: void TokenAnnotator::setCommentLineLevels( SmallVectorImpl<AnnotatedLine *> &Lines) { const AnnotatedLine *NextNonCommentLine = nullptr; - for (AnnotatedLine *AL : llvm::reverse(Lines)) { + for (AnnotatedLine *Line : llvm::reverse(Lines)) { + assert(Line->First); bool CommentLine = true; - for (const FormatToken *Tok = AL->First; Tok; Tok = Tok->Next) { + for (const FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) { if (!Tok->is(tok::comment)) { CommentLine = false; break; @@ -2357,20 +2369,21 @@ void TokenAnnotator::setCommentLineLevels( if (NextNonCommentLine && CommentLine && NextNonCommentLine->First->NewlinesBefore <= 1 && NextNonCommentLine->First->OriginalColumn == - AL->First->OriginalColumn) { + Line->First->OriginalColumn) { // Align comments for preprocessor lines with the # in column 0 if // preprocessor lines are not indented. Otherwise, align with the next // line. - AL->Level = (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash && - (NextNonCommentLine->Type == LT_PreprocessorDirective || - NextNonCommentLine->Type == LT_ImportStatement)) - ? 0 - : NextNonCommentLine->Level; + Line->Level = + (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash && + (NextNonCommentLine->Type == LT_PreprocessorDirective || + NextNonCommentLine->Type == LT_ImportStatement)) + ? 0 + : NextNonCommentLine->Level; } else { - NextNonCommentLine = AL->First->isNot(tok::r_brace) ? AL : nullptr; + NextNonCommentLine = Line->First->isNot(tok::r_brace) ? Line : nullptr; } - setCommentLineLevels(AL->Children); + setCommentLineLevels(Line->Children); } } @@ -2549,11 +2562,8 @@ bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine &Line) const { } void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { - for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(), - E = Line.Children.end(); - I != E; ++I) { - calculateFormattingInformation(**I); - } + for (AnnotatedLine *ChildLine : Line.Children) + calculateFormattingInformation(*ChildLine); Line.First->TotalLength = Line.First->IsMultiline ? Style.ColumnLimit @@ -2569,9 +2579,9 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { while (Current) { if (isFunctionDeclarationName(Style.isCpp(), *Current, Line)) Current->setType(TT_FunctionDeclarationName); + const FormatToken *Prev = Current->Previous; if (Current->is(TT_LineComment)) { - if (Current->Previous->is(BK_BracedInit) && - Current->Previous->opensScope()) + if (Prev->is(BK_BracedInit) && Prev->opensScope()) Current->SpacesRequiredBefore = (Style.Cpp11BracedListStyle && !Style.SpacesInParentheses) ? 0 : 1; else @@ -2612,12 +2622,11 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { Current->CanBreakBefore = Current->MustBreakBefore || canBreakBefore(Line, *Current); unsigned ChildSize = 0; - if (Current->Previous->Children.size() == 1) { - FormatToken &LastOfChild = *Current->Previous->Children[0]->Last; + if (Prev->Children.size() == 1) { + FormatToken &LastOfChild = *Prev->Children[0]->Last; ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit : LastOfChild.TotalLength + 1; } - const FormatToken *Prev = Current->Previous; if (Current->MustBreakBefore || Prev->Children.size() > 1 || (Prev->Children.size() == 1 && Prev->Children[0]->First->MustBreakBefore) || @@ -2857,6 +2866,8 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, Left.Previous->isOneOf(tok::identifier, tok::greater)) return 500; + if (Left.is(tok::l_paren) && Style.PenaltyBreakOpenParenthesis != 0) + return Style.PenaltyBreakOpenParenthesis; if (Left.is(tok::l_paren) && InFunctionDecl && Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign) return 100; @@ -2921,9 +2932,15 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, } bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const { - return Style.SpaceBeforeParens == FormatStyle::SBPO_Always || - (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses && - Right.ParameterCount > 0); + if (Style.SpaceBeforeParens == FormatStyle::SBPO_Always) + return true; + if (Right.is(TT_OverloadedOperatorLParen) && + Style.SpaceBeforeParensOptions.AfterOverloadedOperator) + return true; + if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses && + Right.ParameterCount > 0) + return true; + return false; } bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, @@ -3290,9 +3307,11 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Right) { const FormatToken &Left = *Right.Previous; - auto HasExistingWhitespace = [&Right]() { - return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd(); - }; + + // If the token is finalized don't touch it (as it could be in a + // clang-format-off section). + if (Left.Finalized) + return Right.hasWhitespaceBefore(); if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo()) return true; // Never ever merge two identifiers. @@ -3307,7 +3326,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, // or import .....; if (Left.is(Keywords.kw_import) && Right.isOneOf(tok::less, tok::ellipsis)) return true; - // No space between module :. + // Space between `module :` and `import :`. if (Left.isOneOf(Keywords.kw_module, Keywords.kw_import) && Right.is(TT_ModulePartitionColon)) return true; @@ -3321,12 +3340,18 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, if (Left.is(tok::ellipsis) && Right.is(tok::identifier) && Line.First->is(Keywords.kw_import)) return false; + // Space in __attribute__((attr)) ::type. + if (Left.is(TT_AttributeParen) && Right.is(tok::coloncolon)) + return true; if (Left.is(tok::kw_operator)) return Right.is(tok::coloncolon); if (Right.is(tok::l_brace) && Right.is(BK_BracedInit) && !Left.opensScope() && Style.SpaceBeforeCpp11BracedList) return true; + if (Left.is(tok::less) && Left.is(TT_OverloadedOperator) && + Right.is(TT_TemplateOpener)) + return true; } else if (Style.Language == FormatStyle::LK_Proto || Style.Language == FormatStyle::LK_TextProto) { if (Right.is(tok::period) && @@ -3351,7 +3376,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, // Preserve the existence of a space before a percent for cases like 0x%04x // and "%d %d" if (Left.is(tok::numeric_constant) && Right.is(tok::percent)) - return HasExistingWhitespace(); + return Right.hasWhitespaceBefore(); } else if (Style.isJson()) { if (Right.is(tok::colon)) return false; @@ -3532,7 +3557,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, return true; } if (Left.is(TT_ImplicitStringLiteral)) - return HasExistingWhitespace(); + return Right.hasWhitespaceBefore(); if (Line.Type == LT_ObjCMethodDecl) { if (Left.is(TT_ObjCMethodSpecifier)) return true; @@ -3617,11 +3642,11 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, return Style.SpaceAfterCStyleCast || Right.isOneOf(TT_BinaryOperator, TT_SelectorName); - auto ShouldAddSpacesInAngles = [this, &HasExistingWhitespace]() { + auto ShouldAddSpacesInAngles = [this, &Right]() { if (this->Style.SpacesInAngles == FormatStyle::SIAS_Always) return true; if (this->Style.SpacesInAngles == FormatStyle::SIAS_Leave) - return HasExistingWhitespace(); + return Right.hasWhitespaceBefore(); return false; }; @@ -3647,7 +3672,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, // Generally don't remove existing spaces between an identifier and "::". // The identifier might actually be a macro name such as ALWAYS_INLINE. If // this turns out to be too lenient, add analysis of the identifier itself. - return HasExistingWhitespace(); + return Right.hasWhitespaceBefore(); if (Right.is(tok::coloncolon) && !Left.isOneOf(tok::l_brace, tok::comment, tok::l_paren)) // Put a space between < and :: in vector< ::std::string > @@ -3856,16 +3881,14 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline); if (Left.isTrailingComment()) return true; - if (Right.Previous->IsUnterminatedLiteral) + if (Left.IsUnterminatedLiteral) return true; - if (Right.is(tok::lessless) && Right.Next && - Right.Previous->is(tok::string_literal) && + if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) && Right.Next->is(tok::string_literal)) return true; // Can break after template<> declaration - if (Right.Previous->ClosesTemplateDeclaration && - Right.Previous->MatchingParen && - Right.Previous->MatchingParen->NestingLevel == 0) { + if (Left.ClosesTemplateDeclaration && Left.MatchingParen && + Left.MatchingParen->NestingLevel == 0) { // Put concepts on the next line e.g. // template<typename T> // concept ... @@ -3898,9 +3921,8 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, // has made a deliberate choice and might have aligned the contents of the // string literal accordingly. Thus, we try keep existing line breaks. return Right.IsMultiline && Right.NewlinesBefore > 0; - if ((Right.Previous->is(tok::l_brace) || - (Right.Previous->is(tok::less) && Right.Previous->Previous && - Right.Previous->Previous->is(tok::equal))) && + if ((Left.is(tok::l_brace) || (Left.is(tok::less) && Left.Previous && + Left.Previous->is(tok::equal))) && Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) { // Don't put enums or option definitions onto single lines in protocol // buffers. @@ -4004,7 +4026,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, Right.is(TT_SelectorName) && !Right.is(tok::r_square) && Right.Next) { // Keep `@submessage` together in: // @submessage { key: value } - if (Right.Previous && Right.Previous->is(tok::at)) + if (Left.is(tok::at)) return false; // Look for the scope opener after selector in cases like: // selector { ... @@ -4300,7 +4322,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, if (Right.is(TT_ImplicitStringLiteral)) return false; - if (Right.is(tok::r_paren) || Right.is(TT_TemplateCloser)) + if (Right.is(TT_TemplateCloser)) return false; if (Right.is(tok::r_square) && Right.MatchingParen && Right.MatchingParen->is(TT_LambdaLSquare)) @@ -4311,6 +4333,18 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, if (Right.is(tok::r_brace)) return Right.MatchingParen && Right.MatchingParen->is(BK_Block); + // We only break before r_paren if we're in a block indented context. + if (Right.is(tok::r_paren)) { + if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) { + return Right.MatchingParen && + !(Right.MatchingParen->Previous && + (Right.MatchingParen->Previous->is(tok::kw_for) || + Right.MatchingParen->Previous->isIf())); + } + + return false; + } + // Allow breaking after a trailing annotation, e.g. after a method // declaration. if (Left.is(TT_TrailingAnnotation)) diff --git contrib/llvm-project/clang/lib/Format/TokenAnnotator.h contrib/llvm-project/clang/lib/Format/TokenAnnotator.h index 6e5e62cd4d82..ecd9dbb0f864 100644 --- contrib/llvm-project/clang/lib/Format/TokenAnnotator.h +++ contrib/llvm-project/clang/lib/Format/TokenAnnotator.h @@ -19,8 +19,6 @@ #include "clang/Format/Format.h" namespace clang { -class SourceManager; - namespace format { enum LineType { @@ -53,10 +51,9 @@ public: // left them in a different state. First->Previous = nullptr; FormatToken *Current = First; - for (auto I = ++Line.Tokens.begin(), E = Line.Tokens.end(); I != E; ++I) { - const UnwrappedLineNode &Node = *I; - Current->Next = I->Tok; - I->Tok->Previous = Current; + for (const UnwrappedLineNode &Node : llvm::drop_begin(Line.Tokens)) { + Current->Next = Node.Tok; + Node.Tok->Previous = Current; Current = Current->Next; Current->Children.clear(); for (const auto &Child : Node.Children) { diff --git contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp index f652a4e7088f..0172a224335c 100644 --- contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp +++ contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -262,14 +262,48 @@ private: } } - // FIXME: TheLine->Level != 0 might or might not be the right check to do. - // If necessary, change to something smarter. - bool MergeShortFunctions = - Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All || - (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && - I[1]->First->is(tok::r_brace)) || - (Style.AllowShortFunctionsOnASingleLine & FormatStyle::SFS_InlineOnly && - TheLine->Level != 0); + auto ShouldMergeShortFunctions = + [this, B = AnnotatedLines.begin()]( + SmallVectorImpl<AnnotatedLine *>::const_iterator I) { + if (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All) + return true; + if (Style.AllowShortFunctionsOnASingleLine >= + FormatStyle::SFS_Empty && + I[1]->First->is(tok::r_brace)) + return true; + + if (Style.AllowShortFunctionsOnASingleLine & + FormatStyle::SFS_InlineOnly) { + // Just checking TheLine->Level != 0 is not enough, because it + // provokes treating functions inside indented namespaces as short. + if (Style.isJavaScript() && (*I)->Last->is(TT_FunctionLBrace)) + return true; + + if ((*I)->Level != 0) { + if (I == B) + return false; + + // TODO: Use IndentTracker to avoid loop? + // Find the last line with lower level. + auto J = I - 1; + for (; J != B; --J) + if ((*J)->Level < (*I)->Level) + break; + + // Check if the found line starts a record. + for (const FormatToken *RecordTok = (*J)->Last; RecordTok; + RecordTok = RecordTok->Previous) + if (RecordTok->is(tok::l_brace)) + return RecordTok->is(TT_RecordLBrace); + + return false; + } + } + + return false; + }; + + bool MergeShortFunctions = ShouldMergeShortFunctions(I); if (Style.CompactNamespaces) { if (auto nsToken = TheLine->First->getNamespaceToken()) { @@ -313,7 +347,8 @@ private: } // Try to merge a control statement block with left brace unwrapped if (TheLine->Last->is(tok::l_brace) && TheLine->First != TheLine->Last && - TheLine->First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for)) { + TheLine->First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for, + TT_ForEachMacro)) { return Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never ? tryMergeSimpleBlock(I, E, Limit) : 0; @@ -336,7 +371,7 @@ private: : 0; } else if (I[1]->First->is(tok::l_brace) && TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, - tok::kw_for)) { + tok::kw_for, TT_ForEachMacro)) { return (Style.BraceWrapping.AfterControlStatement == FormatStyle::BWACS_Always) ? tryMergeSimpleBlock(I, E, Limit) @@ -391,7 +426,7 @@ private: } } - // Try to merge a block with left brace wrapped that wasn't yet covered + // Try to merge a block with left brace unwrapped that wasn't yet covered if (TheLine->Last->is(tok::l_brace)) { const FormatToken *Tok = TheLine->First; bool ShouldMerge = false; @@ -451,7 +486,8 @@ private: ? tryMergeSimpleControlStatement(I, E, Limit) : 0; } - if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while, tok::kw_do)) { + if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while, tok::kw_do, + TT_ForEachMacro)) { return Style.AllowShortLoopsOnASingleLine ? tryMergeSimpleControlStatement(I, E, Limit) : 0; @@ -499,13 +535,14 @@ private: if (!Line.First->is(tok::kw_do) && !Line.First->is(tok::kw_else) && !Line.Last->is(tok::kw_else) && Line.Last->isNot(tok::r_paren)) return 0; - // Only merge do while if do is the only statement on the line. + // Only merge `do while` if `do` is the only statement on the line. if (Line.First->is(tok::kw_do) && !Line.Last->is(tok::kw_do)) return 0; if (1 + I[1]->Last->TotalLength > Limit) return 0; + // Don't merge with loops, ifs, a single semicolon or a line comment. if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for, tok::kw_while, - TT_LineComment)) + TT_ForEachMacro, TT_LineComment)) return 0; // Only inline simple if's (no nested if or else), unless specified if (Style.AllowShortIfStatementsOnASingleLine == @@ -593,8 +630,8 @@ private: } if (Line.First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, tok::kw_do, tok::kw_try, tok::kw___try, tok::kw_catch, - tok::kw___finally, tok::kw_for, tok::r_brace, - Keywords.kw___except)) { + tok::kw___finally, tok::kw_for, TT_ForEachMacro, + tok::r_brace, Keywords.kw___except)) { if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) return 0; if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Empty && @@ -614,12 +651,14 @@ private: I + 2 != E && !I[2]->First->is(tok::r_brace)) return 0; if (!Style.AllowShortLoopsOnASingleLine && - Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for) && + Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for, + TT_ForEachMacro) && !Style.BraceWrapping.AfterControlStatement && !I[1]->First->is(tok::r_brace)) return 0; if (!Style.AllowShortLoopsOnASingleLine && - Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for) && + Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for, + TT_ForEachMacro) && Style.BraceWrapping.AfterControlStatement == FormatStyle::BWACS_Always && I + 2 != E && !I[2]->First->is(tok::r_brace)) @@ -1060,9 +1099,9 @@ private: FormatDecision LastFormat = Node->State.NextToken->getDecision(); if (LastFormat == FD_Unformatted || LastFormat == FD_Continue) - addNextStateToQueue(Penalty, Node, /*NewLine=*/false, Count, Queue); + addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue); if (LastFormat == FD_Unformatted || LastFormat == FD_Break) - addNextStateToQueue(Penalty, Node, /*NewLine=*/true, Count, Queue); + addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue); } if (Queue.empty()) { @@ -1088,7 +1127,7 @@ private: /// Assume the current state is \p PreviousNode and has been reached with a /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true. void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode, - bool NewLine, unsigned &Count, QueueType &Queue) { + bool NewLine, unsigned *Count, QueueType *Queue) { if (NewLine && !Indenter->canBreak(PreviousNode->State)) return; if (!NewLine && Indenter->mustBreak(PreviousNode->State)) @@ -1101,29 +1140,29 @@ private: Penalty += Indenter->addTokenToState(Node->State, NewLine, true); - Queue.push(QueueItem(OrderedPenalty(Penalty, Count), Node)); - ++Count; + Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node)); + ++(*Count); } /// Applies the best formatting by reconstructing the path in the /// solution space that leads to \c Best. void reconstructPath(LineState &State, StateNode *Best) { - std::deque<StateNode *> Path; + llvm::SmallVector<StateNode *> Path; // We do not need a break before the initial token. while (Best->Previous) { - Path.push_front(Best); + Path.push_back(Best); Best = Best->Previous; } - for (auto I = Path.begin(), E = Path.end(); I != E; ++I) { + for (const auto &Node : llvm::reverse(Path)) { unsigned Penalty = 0; - formatChildren(State, (*I)->NewLine, /*DryRun=*/false, Penalty); - Penalty += Indenter->addTokenToState(State, (*I)->NewLine, false); + formatChildren(State, Node->NewLine, /*DryRun=*/false, Penalty); + Penalty += Indenter->addTokenToState(State, Node->NewLine, false); LLVM_DEBUG({ - printLineState((*I)->Previous->State); - if ((*I)->NewLine) { + printLineState(Node->Previous->State); + if (Node->NewLine) { llvm::dbgs() << "Penalty for placing " - << (*I)->Previous->State.NextToken->Tok.getName() + << Node->Previous->State.NextToken->Tok.getName() << " on a new line: " << Penalty << "\n"; } }); @@ -1162,7 +1201,9 @@ unsigned UnwrappedLineFormatter::format( bool FirstLine = true; for (const AnnotatedLine *Line = Joiner.getNextMergedLine(DryRun, IndentTracker); - Line; Line = NextLine, FirstLine = false) { + Line; PrevPrevLine = PreviousLine, PreviousLine = Line, Line = NextLine, + FirstLine = false) { + assert(Line->First); const AnnotatedLine &TheLine = *Line; unsigned Indent = IndentTracker.getIndent(); @@ -1190,7 +1231,7 @@ unsigned UnwrappedLineFormatter::format( if (ShouldFormat && TheLine.Type != LT_Invalid) { if (!DryRun) { - bool LastLine = Line->First->is(tok::eof); + bool LastLine = TheLine.First->is(tok::eof); formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines, Indent, LastLine ? LastStartColumn : NextStartColumn + Indent); } @@ -1252,8 +1293,6 @@ unsigned UnwrappedLineFormatter::format( } if (!DryRun) markFinalized(TheLine.First); - PrevPrevLine = PreviousLine; - PreviousLine = &TheLine; } PenaltyCache[CacheKey] = Penalty; return Penalty; diff --git contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp index b6e55aab708f..35be2fa3eb62 100644 --- contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp +++ contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp @@ -14,6 +14,7 @@ #include "UnwrappedLineParser.h" #include "FormatToken.h" +#include "TokenAnnotator.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -32,7 +33,7 @@ public: // Returns the next token in the token stream. virtual FormatToken *getNextToken() = 0; - // Returns the token precedint the token returned by the last call to + // Returns the token preceding the token returned by the last call to // getNextToken() in the token stream, or nullptr if no such token exists. virtual FormatToken *getPreviousToken() = 0; @@ -57,7 +58,7 @@ namespace { class ScopedDeclarationState { public: - ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack, + ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack, bool MustBeDeclaration) : Line(Line), Stack(Stack) { Line.MustBeDeclaration = MustBeDeclaration; @@ -73,7 +74,7 @@ public: private: UnwrappedLine &Line; - std::vector<bool> &Stack; + llvm::BitVector &Stack; }; static bool isLineComment(const FormatToken &FormatTok) { @@ -246,8 +247,7 @@ public: } FormatToken *getPreviousToken() override { - assert(Position > 0); - return Tokens[Position - 1]; + return Position > 0 ? Tokens[Position - 1] : nullptr; } FormatToken *peekNextToken() override { @@ -316,6 +316,7 @@ void UnwrappedLineParser::reset() { PreprocessorDirectives.clear(); CurrentLines = &Lines; DeclarationScopeStack.clear(); + NestedTooDeep.clear(); PPStack.clear(); Line->FirstStartColumn = FirstStartColumn; } @@ -343,11 +344,9 @@ void UnwrappedLineParser::parse() { pushToken(FormatTok); addUnwrappedLine(); - for (SmallVectorImpl<UnwrappedLine>::iterator I = Lines.begin(), - E = Lines.end(); - I != E; ++I) { - Callback.consumeUnwrappedLine(*I); - } + for (const UnwrappedLine &Line : Lines) + Callback.consumeUnwrappedLine(Line); + Callback.finishRun(); Lines.clear(); while (!PPLevelBranchIndex.empty() && @@ -431,7 +430,47 @@ void UnwrappedLineParser::parseCSharpAttribute() { } while (!eof()); } -void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) { +bool UnwrappedLineParser::precededByCommentOrPPDirective() const { + if (!Lines.empty() && Lines.back().InPPDirective) + return true; + + const FormatToken *Previous = Tokens->getPreviousToken(); + return Previous && Previous->is(tok::comment) && + (Previous->IsMultiline || Previous->NewlinesBefore > 0); +} + +bool UnwrappedLineParser::mightFitOnOneLine() const { + const auto ColumnLimit = Style.ColumnLimit; + if (ColumnLimit == 0) + return true; + + if (Lines.empty()) + return true; + + const auto &PreviousLine = Lines.back(); + const auto &Tokens = PreviousLine.Tokens; + assert(!Tokens.empty()); + const auto *LastToken = Tokens.back().Tok; + assert(LastToken); + if (!LastToken->isOneOf(tok::semi, tok::comment)) + return true; + + AnnotatedLine Line(PreviousLine); + assert(Line.Last == LastToken); + + TokenAnnotator Annotator(Style, Keywords); + Annotator.annotate(Line); + Annotator.calculateFormattingInformation(Line); + + return Line.Level * Style.IndentWidth + LastToken->TotalLength <= ColumnLimit; +} + +// Returns true if a simple block, or false otherwise. (A simple block has a +// single statement that fits on a single line.) +bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace, IfStmtKind *IfKind) { + const bool IsPrecededByCommentOrPPDirective = + !Style.RemoveBracesLLVM || precededByCommentOrPPDirective(); + unsigned StatementCount = 0; bool SwitchLabelEncountered = false; do { tok::TokenKind kind = FormatTok->Tok.getKind(); @@ -452,11 +491,24 @@ void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) { if (!FormatTok->is(TT_MacroBlockBegin) && tryToParseBracedList()) continue; parseBlock(); + ++StatementCount; + assert(StatementCount > 0 && "StatementCount overflow!"); addUnwrappedLine(); break; case tok::r_brace: - if (HasOpeningBrace) - return; + if (HasOpeningBrace) { + if (!Style.RemoveBracesLLVM) + return false; + if (FormatTok->isNot(tok::r_brace) || StatementCount != 1 || + IsPrecededByCommentOrPPDirective || + precededByCommentOrPPDirective()) { + return false; + } + const FormatToken *Next = Tokens->peekNextToken(); + if (Next->is(tok::comment) && Next->NewlinesBefore == 0) + return false; + return mightFitOnOneLine(); + } nextToken(); addUnwrappedLine(); break; @@ -496,10 +548,13 @@ void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) { } LLVM_FALLTHROUGH; default: - parseStructuralElement(!HasOpeningBrace); + parseStructuralElement(IfKind, !HasOpeningBrace); + ++StatementCount; + assert(StatementCount > 0 && "StatementCount overflow!"); break; } } while (!eof()); + return false; } void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { @@ -655,11 +710,13 @@ size_t UnwrappedLineParser::computePPHash() const { return h; } -void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels, - bool MunchSemi, - bool UnindentWhitesmithsBraces) { +UnwrappedLineParser::IfStmtKind +UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels, + bool MunchSemi, + bool UnindentWhitesmithsBraces) { assert(FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) && "'{' or macro block token expected"); + FormatToken *Tok = FormatTok; const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin); FormatTok->setBlockKind(BK_Block); @@ -694,16 +751,28 @@ void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels, MustBeDeclaration); if (AddLevels > 0u && Style.BreakBeforeBraces != FormatStyle::BS_Whitesmiths) Line->Level += AddLevels; - parseLevel(/*HasOpeningBrace=*/true); + + IfStmtKind IfKind = IfStmtKind::NotIf; + const bool SimpleBlock = parseLevel(/*HasOpeningBrace=*/true, &IfKind); if (eof()) - return; + return IfKind; if (MacroBlock ? !FormatTok->is(TT_MacroBlockEnd) : !FormatTok->is(tok::r_brace)) { Line->Level = InitialLevel; FormatTok->setBlockKind(BK_Block); - return; + return IfKind; + } + + if (SimpleBlock && Tok->is(tok::l_brace)) { + assert(FormatTok->is(tok::r_brace)); + const FormatToken *Previous = Tokens->getPreviousToken(); + assert(Previous); + if (Previous->isNot(tok::r_brace) || Previous->Optional) { + Tok->MatchingParen = FormatTok; + FormatTok->MatchingParen = Tok; + } } size_t PPEndHash = computePPHash(); @@ -734,6 +803,8 @@ void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels, CurrentLines->size() - 1; } } + + return IfKind; } static bool isGoogScope(const UnwrappedLine &Line) { @@ -782,6 +853,8 @@ static bool ShouldBreakBeforeBrace(const FormatStyle &Style, return Style.BraceWrapping.AfterUnion; if (InitialToken.is(tok::kw_struct)) return Style.BraceWrapping.AfterStruct; + if (InitialToken.is(tok::kw_enum)) + return Style.BraceWrapping.AfterEnum; return false; } @@ -969,8 +1042,7 @@ void UnwrappedLineParser::parsePPDefine() { nextToken(); if (FormatTok->Tok.getKind() == tok::l_paren && - FormatTok->WhitespaceRange.getBegin() == - FormatTok->WhitespaceRange.getEnd()) { + !FormatTok->hasWhitespaceBefore()) { parseParens(); } if (Style.IndentPPDirectives != FormatStyle::PPDIS_None) @@ -1186,7 +1258,8 @@ void UnwrappedLineParser::readTokenWithJavaScriptASI() { return addUnwrappedLine(); } -void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) { +void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind, + bool IsTopLevel) { if (Style.Language == FormatStyle::LK_TableGen && FormatTok->is(tok::pp_include)) { nextToken(); @@ -1229,7 +1302,7 @@ void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) { if (Style.isJavaScript() && Line->MustBeDeclaration) // field/method declaration. break; - parseIfThenElse(); + parseIfThenElse(IfKind); return; case tok::kw_for: case tok::kw_while: @@ -1523,8 +1596,16 @@ void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) { // structural element. // FIXME: Figure out cases where this is not true, and add projections // for them (the one we know is missing are lambdas). - if (Style.BraceWrapping.AfterFunction) + if (Style.Language == FormatStyle::LK_Java && + Line->Tokens.front().Tok->is(Keywords.kw_synchronized)) { + // If necessary, we could set the type to something different than + // TT_FunctionLBrace. + if (Style.BraceWrapping.AfterControlStatement == + FormatStyle::BWACS_Always) + addUnwrappedLine(); + } else if (Style.BraceWrapping.AfterFunction) { addUnwrappedLine(); + } FormatTok->setType(TT_FunctionLBrace); parseBlock(); addUnwrappedLine(); @@ -1601,6 +1682,8 @@ void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) { // See if the following token should start a new unwrapped line. StringRef Text = FormatTok->TokenText; + + FormatToken *PreviousToken = FormatTok; nextToken(); // JS doesn't have macros, and within classes colons indicate fields, not @@ -1629,6 +1712,7 @@ void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) { if (FollowedByNewline && (Text.size() >= 5 || FunctionLike) && tokenCanStartNewLine(*FormatTok) && Text == Text.upper()) { + PreviousToken->setType(TT_FunctionLikeOrFreestandingMacro); addUnwrappedLine(); return; } @@ -1772,6 +1856,7 @@ bool UnwrappedLineParser::tryToParseLambda() { return false; bool SeenArrow = false; + bool InTemplateParameterList = false; while (FormatTok->isNot(tok::l_brace)) { if (FormatTok->isSimpleTypeSpecifier()) { @@ -1784,6 +1869,17 @@ bool UnwrappedLineParser::tryToParseLambda() { case tok::l_paren: parseParens(); break; + case tok::l_square: + parseSquare(); + break; + case tok::kw_class: + case tok::kw_template: + case tok::kw_typename: + assert(FormatTok->Previous); + if (FormatTok->Previous->is(tok::less)) + InTemplateParameterList = true; + nextToken(); + break; case tok::amp: case tok::star: case tok::kw_const: @@ -1793,11 +1889,8 @@ bool UnwrappedLineParser::tryToParseLambda() { case tok::identifier: case tok::numeric_constant: case tok::coloncolon: - case tok::kw_class: case tok::kw_mutable: case tok::kw_noexcept: - case tok::kw_template: - case tok::kw_typename: nextToken(); break; // Specialization of a template with an integer parameter can contain @@ -1834,7 +1927,7 @@ bool UnwrappedLineParser::tryToParseLambda() { case tok::ellipsis: case tok::kw_true: case tok::kw_false: - if (SeenArrow) { + if (SeenArrow || InTemplateParameterList) { nextToken(); break; } @@ -2128,7 +2221,39 @@ void UnwrappedLineParser::parseSquare(bool LambdaIntroducer) { } while (!eof()); } -void UnwrappedLineParser::parseIfThenElse() { +void UnwrappedLineParser::keepAncestorBraces() { + if (!Style.RemoveBracesLLVM) + return; + + const int MaxNestingLevels = 2; + const int Size = NestedTooDeep.size(); + if (Size >= MaxNestingLevels) + NestedTooDeep[Size - MaxNestingLevels] = true; + NestedTooDeep.push_back(false); +} + +static void markOptionalBraces(FormatToken *LeftBrace) { + if (!LeftBrace) + return; + + assert(LeftBrace->is(tok::l_brace)); + + FormatToken *RightBrace = LeftBrace->MatchingParen; + if (!RightBrace) { + assert(!LeftBrace->Optional); + return; + } + + assert(RightBrace->is(tok::r_brace)); + assert(RightBrace->MatchingParen == LeftBrace); + assert(LeftBrace->Optional == RightBrace->Optional); + + LeftBrace->Optional = true; + RightBrace->Optional = true; +} + +FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind, + bool KeepBraces) { auto HandleAttributes = [this]() { // Handle AttributeMacro, e.g. `if (x) UNLIKELY`. if (FormatTok->is(TT_AttributeMacro)) @@ -2145,10 +2270,17 @@ void UnwrappedLineParser::parseIfThenElse() { if (FormatTok->Tok.is(tok::l_paren)) parseParens(); HandleAttributes(); + bool NeedsUnwrappedLine = false; + keepAncestorBraces(); + + FormatToken *IfLeftBrace = nullptr; + IfStmtKind IfBlockKind = IfStmtKind::NotIf; + if (FormatTok->Tok.is(tok::l_brace)) { + IfLeftBrace = FormatTok; CompoundStatementIndenter Indenter(this, Style, Line->Level); - parseBlock(); + IfBlockKind = parseBlock(); if (Style.BraceWrapping.BeforeElse) addUnwrappedLine(); else @@ -2159,22 +2291,48 @@ void UnwrappedLineParser::parseIfThenElse() { parseStructuralElement(); --Line->Level; } + + bool KeepIfBraces = false; + if (Style.RemoveBracesLLVM) { + assert(!NestedTooDeep.empty()); + KeepIfBraces = (IfLeftBrace && !IfLeftBrace->MatchingParen) || + NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly || + IfBlockKind == IfStmtKind::IfElseIf; + } + + FormatToken *ElseLeftBrace = nullptr; + IfStmtKind Kind = IfStmtKind::IfOnly; + if (FormatTok->Tok.is(tok::kw_else)) { + if (Style.RemoveBracesLLVM) { + NestedTooDeep.back() = false; + Kind = IfStmtKind::IfElse; + } nextToken(); HandleAttributes(); if (FormatTok->Tok.is(tok::l_brace)) { + ElseLeftBrace = FormatTok; CompoundStatementIndenter Indenter(this, Style, Line->Level); - parseBlock(); + if (parseBlock() == IfStmtKind::IfOnly) + Kind = IfStmtKind::IfElseIf; addUnwrappedLine(); } else if (FormatTok->Tok.is(tok::kw_if)) { FormatToken *Previous = Tokens->getPreviousToken(); - bool PrecededByComment = Previous && Previous->is(tok::comment); - if (PrecededByComment) { + const bool IsPrecededByComment = Previous && Previous->is(tok::comment); + if (IsPrecededByComment) { addUnwrappedLine(); ++Line->Level; } - parseIfThenElse(); - if (PrecededByComment) + bool TooDeep = true; + if (Style.RemoveBracesLLVM) { + Kind = IfStmtKind::IfElseIf; + TooDeep = NestedTooDeep.pop_back_val(); + } + ElseLeftBrace = + parseIfThenElse(/*IfKind=*/nullptr, KeepBraces || KeepIfBraces); + if (Style.RemoveBracesLLVM) + NestedTooDeep.push_back(TooDeep); + if (IsPrecededByComment) --Line->Level; } else { addUnwrappedLine(); @@ -2184,9 +2342,40 @@ void UnwrappedLineParser::parseIfThenElse() { addUnwrappedLine(); --Line->Level; } - } else if (NeedsUnwrappedLine) { - addUnwrappedLine(); + } else { + if (Style.RemoveBracesLLVM) + KeepIfBraces = KeepIfBraces || IfBlockKind == IfStmtKind::IfElse; + if (NeedsUnwrappedLine) + addUnwrappedLine(); + } + + if (!Style.RemoveBracesLLVM) + return nullptr; + + assert(!NestedTooDeep.empty()); + const bool KeepElseBraces = + (ElseLeftBrace && !ElseLeftBrace->MatchingParen) || NestedTooDeep.back(); + + NestedTooDeep.pop_back(); + + if (!KeepBraces && !KeepIfBraces && !KeepElseBraces) { + markOptionalBraces(IfLeftBrace); + markOptionalBraces(ElseLeftBrace); + } else if (IfLeftBrace) { + FormatToken *IfRightBrace = IfLeftBrace->MatchingParen; + if (IfRightBrace) { + assert(IfRightBrace->MatchingParen == IfLeftBrace); + assert(!IfLeftBrace->Optional); + assert(!IfRightBrace->Optional); + IfLeftBrace->MatchingParen = nullptr; + IfRightBrace->MatchingParen = nullptr; + } } + + if (IfKind) + *IfKind = Kind; + + return IfLeftBrace; } void UnwrappedLineParser::parseTryCatch() { @@ -2224,6 +2413,9 @@ void UnwrappedLineParser::parseTryCatch() { if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_paren)) { parseParens(); } + + keepAncestorBraces(); + if (FormatTok->is(tok::l_brace)) { CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(); @@ -2241,7 +2433,7 @@ void UnwrappedLineParser::parseTryCatch() { parseStructuralElement(); --Line->Level; } - while (1) { + while (true) { if (FormatTok->is(tok::at)) nextToken(); if (!(FormatTok->isOneOf(tok::kw_catch, Keywords.kw___except, @@ -2257,8 +2449,11 @@ void UnwrappedLineParser::parseTryCatch() { parseParens(); continue; } - if (FormatTok->isOneOf(tok::semi, tok::r_brace, tok::eof)) + if (FormatTok->isOneOf(tok::semi, tok::r_brace, tok::eof)) { + if (Style.RemoveBracesLLVM) + NestedTooDeep.pop_back(); return; + } nextToken(); } NeedsUnwrappedLine = false; @@ -2269,6 +2464,10 @@ void UnwrappedLineParser::parseTryCatch() { else NeedsUnwrappedLine = true; } + + if (Style.RemoveBracesLLVM) + NestedTooDeep.pop_back(); + if (NeedsUnwrappedLine) addUnwrappedLine(); } @@ -2283,7 +2482,8 @@ void UnwrappedLineParser::parseNamespace() { parseParens(); } else { while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline, - tok::l_square, tok::period)) { + tok::l_square, tok::period) || + (Style.isCSharp() && FormatTok->is(tok::kw_union))) { if (FormatTok->is(tok::l_square)) parseSquare(); else @@ -2375,9 +2575,18 @@ void UnwrappedLineParser::parseForOrWhileLoop() { nextToken(); if (FormatTok->Tok.is(tok::l_paren)) parseParens(); + + keepAncestorBraces(); + if (FormatTok->Tok.is(tok::l_brace)) { + FormatToken *LeftBrace = FormatTok; CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(); + if (Style.RemoveBracesLLVM) { + assert(!NestedTooDeep.empty()); + if (!NestedTooDeep.back()) + markOptionalBraces(LeftBrace); + } addUnwrappedLine(); } else { addUnwrappedLine(); @@ -2385,11 +2594,17 @@ void UnwrappedLineParser::parseForOrWhileLoop() { parseStructuralElement(); --Line->Level; } + + if (Style.RemoveBracesLLVM) + NestedTooDeep.pop_back(); } void UnwrappedLineParser::parseDoWhile() { assert(FormatTok->Tok.is(tok::kw_do) && "'do' expected"); nextToken(); + + keepAncestorBraces(); + if (FormatTok->Tok.is(tok::l_brace)) { CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(); @@ -2402,6 +2617,9 @@ void UnwrappedLineParser::parseDoWhile() { --Line->Level; } + if (Style.RemoveBracesLLVM) + NestedTooDeep.pop_back(); + // FIXME: Add error handling. if (!FormatTok->Tok.is(tok::kw_while)) { addUnwrappedLine(); @@ -2438,7 +2656,7 @@ void UnwrappedLineParser::parseLabel(bool LeftAlignLabel) { addUnwrappedLine(); if (!Style.IndentCaseBlocks && Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) { - Line->Level++; + ++Line->Level; } } parseStructuralElement(); @@ -2471,6 +2689,9 @@ void UnwrappedLineParser::parseSwitch() { nextToken(); if (FormatTok->Tok.is(tok::l_paren)) parseParens(); + + keepAncestorBraces(); + if (FormatTok->Tok.is(tok::l_brace)) { CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(); @@ -2481,6 +2702,9 @@ void UnwrappedLineParser::parseSwitch() { parseStructuralElement(); --Line->Level; } + + if (Style.RemoveBracesLLVM) + NestedTooDeep.pop_back(); } void UnwrappedLineParser::parseAccessSpecifier() { @@ -2597,7 +2821,7 @@ void UnwrappedLineParser::parseRequires() { if (FormatTok->Previous && FormatTok->Previous->is(tok::greater)) { addUnwrappedLine(); if (Style.IndentRequires) { - Line->Level++; + ++Line->Level; } } nextToken(); @@ -2606,12 +2830,12 @@ void UnwrappedLineParser::parseRequires() { } bool UnwrappedLineParser::parseEnum() { + const FormatToken &InitialToken = *FormatTok; + // Won't be 'enum' for NS_ENUMs. if (FormatTok->Tok.is(tok::kw_enum)) nextToken(); - const FormatToken &InitialToken = *FormatTok; - // In TypeScript, "enum" can also be used as property name, e.g. in interface // declarations. An "enum" keyword followed by a colon would be a syntax // error and thus assume it is just an identifier. @@ -2645,6 +2869,7 @@ bool UnwrappedLineParser::parseEnum() { // Just a declaration or something is wrong. if (FormatTok->isNot(tok::l_brace)) return true; + FormatTok->setType(TT_RecordLBrace); FormatTok->setBlockKind(BK_Block); if (Style.Language == FormatStyle::LK_Java) { @@ -2864,6 +3089,15 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { if (!tryToParseBracedList()) break; } + if (FormatTok->is(tok::l_square)) { + FormatToken *Previous = FormatTok->Previous; + if (!Previous || Previous->isNot(tok::r_paren)) { + // Don't try parsing a lambda if we had a closing parenthesis before, + // it was probably a pointer to an array: int (*)[]. + if (!tryToParseLambda()) + break; + } + } if (FormatTok->Tok.is(tok::semi)) return; if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { @@ -2876,6 +3110,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { } } if (FormatTok->Tok.is(tok::l_brace)) { + FormatTok->setType(TT_RecordLBrace); if (ParseAsExpr) { parseChildBlock(); } else { @@ -3264,10 +3499,7 @@ continuesLineCommentSection(const FormatToken &FormatTok, void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) { bool JustComments = Line->Tokens.empty(); - for (SmallVectorImpl<FormatToken *>::const_iterator - I = CommentsBeforeNextToken.begin(), - E = CommentsBeforeNextToken.end(); - I != E; ++I) { + for (FormatToken *Tok : CommentsBeforeNextToken) { // Line comments that belong to the same line comment section are put on the // same line since later we might want to reflow content between them. // Additional fine-grained breaking of line comment sections is controlled @@ -3276,11 +3508,11 @@ void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) { // // FIXME: Consider putting separate line comment sections as children to the // unwrapped line instead. - (*I)->ContinuesLineCommentSection = - continuesLineCommentSection(**I, *Line, CommentPragmasRegex); - if (isOnNewLine(**I) && JustComments && !(*I)->ContinuesLineCommentSection) + Tok->ContinuesLineCommentSection = + continuesLineCommentSection(*Tok, *Line, CommentPragmasRegex); + if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection) addUnwrappedLine(); - pushToken(*I); + pushToken(Tok); } if (NewlineBeforeNext && JustComments) addUnwrappedLine(); diff --git contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h index 0c79723d50fc..3f64d57c7bff 100644 --- contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h +++ contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h @@ -18,6 +18,7 @@ #include "FormatToken.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Format/Format.h" +#include "llvm/ADT/BitVector.h" #include "llvm/Support/Regex.h" #include <stack> #include <vector> @@ -81,12 +82,21 @@ public: void parse(); private: + enum class IfStmtKind { + NotIf, // Not an if statement. + IfOnly, // An if statement without the else clause. + IfElse, // An if statement followed by else but not else if. + IfElseIf // An if statement followed by else if. + }; + void reset(); void parseFile(); - void parseLevel(bool HasOpeningBrace); - void parseBlock(bool MustBeDeclaration = false, unsigned AddLevels = 1u, - bool MunchSemi = true, - bool UnindentWhitesmithsBraces = false); + bool precededByCommentOrPPDirective() const; + bool mightFitOnOneLine() const; + bool parseLevel(bool HasOpeningBrace, IfStmtKind *IfKind = nullptr); + IfStmtKind parseBlock(bool MustBeDeclaration = false, unsigned AddLevels = 1u, + bool MunchSemi = true, + bool UnindentWhitesmithsBraces = false); void parseChildBlock(); void parsePPDirective(); void parsePPDefine(); @@ -96,13 +106,15 @@ private: void parsePPEndIf(); void parsePPUnknown(); void readTokenWithJavaScriptASI(); - void parseStructuralElement(bool IsTopLevel = false); + void parseStructuralElement(IfStmtKind *IfKind = nullptr, + bool IsTopLevel = false); bool tryToParseBracedList(); bool parseBracedList(bool ContinueOnSemicolons = false, bool IsEnum = false, tok::TokenKind ClosingBraceKind = tok::r_brace); void parseParens(); void parseSquare(bool LambdaIntroducer = false); - void parseIfThenElse(); + void keepAncestorBraces(); + FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false); void parseTryCatch(); void parseForOrWhileLoop(); void parseDoWhile(); @@ -220,7 +232,7 @@ private: // We store for each line whether it must be a declaration depending on // whether we are in a compound statement or not. - std::vector<bool> DeclarationScopeStack; + llvm::BitVector DeclarationScopeStack; const FormatStyle &Style; const AdditionalKeywords &Keywords; @@ -235,6 +247,10 @@ private: // owned outside of and handed into the UnwrappedLineParser. ArrayRef<FormatToken *> AllTokens; + // Keeps a stack of the states of nested control statements (true if the + // statement contains more than some predefined number of nested statements). + SmallVector<bool, 8> NestedTooDeep; + // Represents preprocessor branch type, so we can find matching // #if/#else/#endif directives. enum PPBranchKind { diff --git contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp index 96a66da0f82b..0d2e507ac587 100644 --- contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp +++ contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp @@ -74,6 +74,12 @@ WhitespaceManager::addReplacement(const tooling::Replacement &Replacement) { return Replaces.add(Replacement); } +bool WhitespaceManager::inputUsesCRLF(StringRef Text, bool DefaultToCRLF) { + size_t LF = Text.count('\n'); + size_t CR = Text.count('\r') * 2; + return LF == CR ? DefaultToCRLF : CR > LF; +} + void WhitespaceManager::replaceWhitespaceInToken( const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars, StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective, @@ -304,7 +310,7 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End, unsigned PreviousNonComment = i - 1; while (PreviousNonComment > Start && Changes[PreviousNonComment].Tok->is(tok::comment)) - PreviousNonComment--; + --PreviousNonComment; if (i != Start && Changes[i].indentAndNestingLevel() > Changes[PreviousNonComment].indentAndNestingLevel()) ScopeStack.push_back(i); @@ -362,6 +368,13 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End, Changes[i].Tok->Previous->is(TT_ConditionalExpr)) return true; + // Continued braced list. + if (ScopeStart > Start + 1 && + Changes[ScopeStart - 2].Tok->isNot(tok::identifier) && + Changes[ScopeStart - 1].Tok->is(tok::l_brace) && + Changes[i].Tok->isNot(tok::r_brace)) + return true; + return false; }; @@ -718,6 +731,11 @@ void WhitespaceManager::alignConsecutiveAssignments() { if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0) return false; + // Do not align operator= overloads. + FormatToken *Previous = C.Tok->getPreviousNonComment(); + if (Previous && Previous->is(tok::kw_operator)) + return false; + return C.Tok->is(tok::equal); }, Changes, /*StartAt=*/0, Style.AlignConsecutiveAssignments); @@ -1160,7 +1178,7 @@ WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start, NextNonComment = NextNonComment->getNextNonComment(); auto j = i; while (Changes[j].Tok != NextNonComment && j < End) - j++; + ++j; if (j < End && Changes[j].NewlinesBefore == 0 && Changes[j].Tok->isNot(tok::r_brace)) { Changes[j].NewlinesBefore = 1; diff --git contrib/llvm-project/clang/lib/Format/WhitespaceManager.h contrib/llvm-project/clang/lib/Format/WhitespaceManager.h index 029f4159b748..42f958f68ba6 100644 --- contrib/llvm-project/clang/lib/Format/WhitespaceManager.h +++ contrib/llvm-project/clang/lib/Format/WhitespaceManager.h @@ -45,6 +45,9 @@ public: bool useCRLF() const { return UseCRLF; } + /// Infers whether the input is using CRLF. + static bool inputUsesCRLF(StringRef Text, bool DefaultToCRLF); + /// Replaces the whitespace in front of \p Tok. Only call once for /// each \c AnnotatedToken. /// @@ -242,7 +245,7 @@ private: /// as described by \p CellDescs. void alignArrayInitializersRightJustified(CellDescriptions &&CellDescs); - /// Align Array Initializers being careful to leftt justify the columns + /// Align Array Initializers being careful to left justify the columns /// as described by \p CellDescs. void alignArrayInitializersLeftJustified(CellDescriptions &&CellDescs); diff --git contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp index 52589677ca28..5f587cc1c023 100644 --- contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp +++ contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp @@ -817,7 +817,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( AST->Reader = new ASTReader( PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {}, /*isysroot=*/"", - /*DisableValidation=*/disableValid, AllowASTWithCompilerErrors); + /*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors); AST->Reader->setListener(std::make_unique<ASTInfoCollector>( *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts, @@ -1922,9 +1922,10 @@ namespace { void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, OverloadCandidate *Candidates, unsigned NumCandidates, - SourceLocation OpenParLoc) override { + SourceLocation OpenParLoc, + bool Braced) override { Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates, - OpenParLoc); + OpenParLoc, Braced); } CodeCompletionAllocator &getAllocator() override { diff --git contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp index 31e7ea3d243d..2465a7e2453b 100644 --- contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp +++ contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp @@ -37,6 +37,7 @@ #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/GlobalModuleIndex.h" #include "clang/Serialization/InMemoryModuleCache.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/BuryPointer.h" #include "llvm/Support/CrashRecoveryContext.h" @@ -996,6 +997,11 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { // DesiredStackSpace available. noteBottomOfStack(); + auto FinishDiagnosticClient = llvm::make_scope_exit([&]() { + // Notify the diagnostic client that all files were processed. + getDiagnosticClient().finish(); + }); + raw_ostream &OS = getVerboseOutputStream(); if (!Act.PrepareToExecute(*this)) @@ -1034,9 +1040,6 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { } } - // Notify the diagnostic client that all files were processed. - getDiagnostics().getClient()->finish(); - if (getDiagnosticOpts().ShowCarets) { // We can have multiple diagnostics sharing one diagnostic client. // Get the total number of warnings/errors from the client. @@ -1414,7 +1417,7 @@ static bool compileModuleAndReadASTBehindLock( StringRef Dir = llvm::sys::path::parent_path(ModuleFileName); llvm::sys::fs::create_directories(Dir); - while (1) { + while (true) { llvm::LockFileManager Locked(ModuleFileName); switch (Locked) { case llvm::LockFileManager::LFS_Error: diff --git contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp index b71addd84bfd..7f1ce3da7e7e 100644 --- contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp +++ contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp @@ -438,7 +438,7 @@ static T extractMaskValue(T KeyPath) { }(EXTRACTOR(KEYPATH)); \ } -static const StringRef GetInputKindName(InputKind IK); +static StringRef GetInputKindName(InputKind IK); static bool FixupInvocation(CompilerInvocation &Invocation, DiagnosticsEngine &Diags, const ArgList &Args, @@ -1814,6 +1814,9 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name; } + if (Opts.PrepareForLTO && Args.hasArg(OPT_mibt_seal)) + Opts.IBTSeal = 1; + for (auto *A : Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) { CodeGenOptions::BitcodeFileToLink F; @@ -2405,6 +2408,7 @@ static const auto &getFrontendActionTable() { {frontend::EmitCodeGenOnly, OPT_emit_codegen_only}, {frontend::EmitCodeGenOnly, OPT_emit_codegen_only}, {frontend::EmitObj, OPT_emit_obj}, + {frontend::ExtractAPI, OPT_extract_api}, {frontend::FixIt, OPT_fixit_EQ}, {frontend::FixIt, OPT_fixit}, @@ -3291,7 +3295,7 @@ static bool IsInputCompatibleWithStandard(InputKind IK, } /// Get language name for given input kind. -static const StringRef GetInputKindName(InputKind IK) { +static StringRef GetInputKindName(InputKind IK) { switch (IK.getLanguage()) { case Language::C: return "C"; @@ -4144,6 +4148,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::EmitLLVMOnly: case frontend::EmitCodeGenOnly: case frontend::EmitObj: + case frontend::ExtractAPI: case frontend::FixIt: case frontend::GenerateModule: case frontend::GenerateModuleInterface: diff --git contrib/llvm-project/clang/lib/Frontend/ExtractAPIConsumer.cpp contrib/llvm-project/clang/lib/Frontend/ExtractAPIConsumer.cpp new file mode 100644 index 000000000000..cdf67f3c327a --- /dev/null +++ contrib/llvm-project/clang/lib/Frontend/ExtractAPIConsumer.cpp @@ -0,0 +1,32 @@ +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Frontend/ASTConsumers.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" + +using namespace clang; + +namespace { +class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> { +public: + bool VisitNamedDecl(NamedDecl *Decl) { + llvm::outs() << Decl->getName() << "\n"; + return true; + } +}; + +class ExtractAPIConsumer : public ASTConsumer { +public: + void HandleTranslationUnit(ASTContext &Context) override { + Visitor.TraverseDecl(Context.getTranslationUnitDecl()); + } + +private: + ExtractAPIVisitor Visitor; +}; +} // namespace + +std::unique_ptr<ASTConsumer> +ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + return std::make_unique<ExtractAPIConsumer>(); +} diff --git contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp index fb8132a5e40a..ad2e6039477f 100644 --- contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp +++ contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp @@ -8,9 +8,10 @@ #include "clang/Frontend/FrontendActions.h" #include "clang/AST/ASTConsumer.h" +#include "clang/AST/Decl.h" #include "clang/Basic/FileManager.h" -#include "clang/Basic/TargetInfo.h" #include "clang/Basic/LangStandard.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Frontend/ASTConsumers.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" @@ -23,6 +24,7 @@ #include "clang/Sema/TemplateInstCallback.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" @@ -310,9 +312,8 @@ bool GenerateHeaderModuleAction::BeginSourceFileAction( auto &HS = CI.getPreprocessor().getHeaderSearchInfo(); SmallVector<Module::Header, 16> Headers; for (StringRef Name : ModuleHeaders) { - const DirectoryLookup *CurDir = nullptr; Optional<FileEntryRef> FE = HS.LookupFile( - Name, SourceLocation(), /*Angled*/ false, nullptr, CurDir, None, + Name, SourceLocation(), /*Angled*/ false, nullptr, nullptr, None, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (!FE) { CI.getDiagnostics().Report(diag::err_module_header_file_not_found) @@ -481,25 +482,92 @@ private: Out << "---" << YAML << "\n"; } + static void printEntryName(const Sema &TheSema, const Decl *Entity, + llvm::raw_string_ostream &OS) { + auto *NamedTemplate = cast<NamedDecl>(Entity); + + PrintingPolicy Policy = TheSema.Context.getPrintingPolicy(); + // FIXME: Also ask for FullyQualifiedNames? + Policy.SuppressDefaultTemplateArgs = false; + NamedTemplate->getNameForDiagnostic(OS, Policy, true); + + if (!OS.str().empty()) + return; + + Decl *Ctx = Decl::castFromDeclContext(NamedTemplate->getDeclContext()); + NamedDecl *NamedCtx = dyn_cast_or_null<NamedDecl>(Ctx); + + if (const auto *Decl = dyn_cast<TagDecl>(NamedTemplate)) { + if (const auto *R = dyn_cast<RecordDecl>(Decl)) { + if (R->isLambda()) { + OS << "lambda at "; + Decl->getLocation().print(OS, TheSema.getSourceManager()); + return; + } + } + OS << "unnamed " << Decl->getKindName(); + return; + } + + if (const auto *Decl = dyn_cast<ParmVarDecl>(NamedTemplate)) { + OS << "unnamed function parameter " << Decl->getFunctionScopeIndex() + << " "; + if (Decl->getFunctionScopeDepth() > 0) + OS << "(at depth " << Decl->getFunctionScopeDepth() << ") "; + OS << "of "; + NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); + return; + } + + if (const auto *Decl = dyn_cast<TemplateTypeParmDecl>(NamedTemplate)) { + if (const Type *Ty = Decl->getTypeForDecl()) { + if (const auto *TTPT = dyn_cast_or_null<TemplateTypeParmType>(Ty)) { + OS << "unnamed template type parameter " << TTPT->getIndex() << " "; + if (TTPT->getDepth() > 0) + OS << "(at depth " << TTPT->getDepth() << ") "; + OS << "of "; + NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); + return; + } + } + } + + if (const auto *Decl = dyn_cast<NonTypeTemplateParmDecl>(NamedTemplate)) { + OS << "unnamed template non-type parameter " << Decl->getIndex() << " "; + if (Decl->getDepth() > 0) + OS << "(at depth " << Decl->getDepth() << ") "; + OS << "of "; + NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); + return; + } + + if (const auto *Decl = dyn_cast<TemplateTemplateParmDecl>(NamedTemplate)) { + OS << "unnamed template template parameter " << Decl->getIndex() << " "; + if (Decl->getDepth() > 0) + OS << "(at depth " << Decl->getDepth() << ") "; + OS << "of "; + NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); + return; + } + + llvm_unreachable("Failed to retrieve a name for this entry!"); + OS << "unnamed identifier"; + } + template <bool BeginInstantiation> static TemplightEntry getTemplightEntry(const Sema &TheSema, const CodeSynthesisContext &Inst) { TemplightEntry Entry; Entry.Kind = toString(Inst.Kind); Entry.Event = BeginInstantiation ? "Begin" : "End"; - if (auto *NamedTemplate = dyn_cast_or_null<NamedDecl>(Inst.Entity)) { - llvm::raw_string_ostream OS(Entry.Name); - PrintingPolicy Policy = TheSema.Context.getPrintingPolicy(); - // FIXME: Also ask for FullyQualifiedNames? - Policy.SuppressDefaultTemplateArgs = false; - NamedTemplate->getNameForDiagnostic(OS, Policy, true); - const PresumedLoc DefLoc = + llvm::raw_string_ostream OS(Entry.Name); + printEntryName(TheSema, Inst.Entity, OS); + const PresumedLoc DefLoc = TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation()); - if(!DefLoc.isInvalid()) - Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" + - std::to_string(DefLoc.getLine()) + ":" + - std::to_string(DefLoc.getColumn()); - } + if (!DefLoc.isInvalid()) + Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" + + std::to_string(DefLoc.getLine()) + ":" + + std::to_string(DefLoc.getColumn()); const PresumedLoc PoiLoc = TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation); if (!PoiLoc.isInvalid()) { diff --git contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp index 629f99110661..a9023a7a1171 100644 --- contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp +++ contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp @@ -194,7 +194,7 @@ static void DefineType(const Twine &MacroName, TargetInfo::IntType Ty, Builder.defineMacro(MacroName, TargetInfo::getTypeName(Ty)); } -static void DefineTypeWidth(StringRef MacroName, TargetInfo::IntType Ty, +static void DefineTypeWidth(const Twine &MacroName, TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { Builder.defineMacro(MacroName, Twine(TI.getTypeWidth(Ty))); } @@ -205,6 +205,16 @@ static void DefineTypeSizeof(StringRef MacroName, unsigned BitWidth, Twine(BitWidth / TI.getCharWidth())); } +// This will generate a macro based on the prefix with `_MAX__` as the suffix +// for the max value representable for the type, and a macro with a `_WIDTH__` +// suffix for the width of the type. +static void DefineTypeSizeAndWidth(const Twine &Prefix, TargetInfo::IntType Ty, + const TargetInfo &TI, + MacroBuilder &Builder) { + DefineTypeSize(Prefix + "_MAX__", Ty, TI, Builder); + DefineTypeWidth(Prefix + "_WIDTH__", Ty, TI, Builder); +} + static void DefineExactWidthIntType(TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { @@ -241,6 +251,8 @@ static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty, if (TypeWidth == 64) Ty = IsSigned ? TI.getInt64Type() : TI.getUInt64Type(); + // We don't need to define a _WIDTH macro for the exact-width types because + // we already know the width. const char *Prefix = IsSigned ? "__INT" : "__UINT"; DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); } @@ -254,7 +266,12 @@ static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned, const char *Prefix = IsSigned ? "__INT_LEAST" : "__UINT_LEAST"; DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder); - DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); + // We only want the *_WIDTH macro for the signed types to avoid too many + // predefined macros (the unsigned width and the signed width are identical.) + if (IsSigned) + DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder); + else + DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder); } @@ -268,8 +285,12 @@ static void DefineFastIntType(unsigned TypeWidth, bool IsSigned, const char *Prefix = IsSigned ? "__INT_FAST" : "__UINT_FAST"; DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder); - DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); - + // We only want the *_WIDTH macro for the signed types to avoid too many + // predefined macros (the unsigned width and the signed width are identical.) + if (IsSigned) + DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder); + else + DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder); } @@ -887,20 +908,26 @@ static void InitializePredefinedMacros(const TargetInfo &TI, assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far"); Builder.defineMacro("__CHAR_BIT__", Twine(TI.getCharWidth())); + Builder.defineMacro("__BOOL_WIDTH__", Twine(TI.getBoolWidth())); + Builder.defineMacro("__SHRT_WIDTH__", Twine(TI.getShortWidth())); + Builder.defineMacro("__INT_WIDTH__", Twine(TI.getIntWidth())); + Builder.defineMacro("__LONG_WIDTH__", Twine(TI.getLongWidth())); + Builder.defineMacro("__LLONG_WIDTH__", Twine(TI.getLongLongWidth())); + DefineTypeSize("__SCHAR_MAX__", TargetInfo::SignedChar, TI, Builder); DefineTypeSize("__SHRT_MAX__", TargetInfo::SignedShort, TI, Builder); DefineTypeSize("__INT_MAX__", TargetInfo::SignedInt, TI, Builder); DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, TI, Builder); DefineTypeSize("__LONG_LONG_MAX__", TargetInfo::SignedLongLong, TI, Builder); - DefineTypeSize("__WCHAR_MAX__", TI.getWCharType(), TI, Builder); - DefineTypeSize("__WINT_MAX__", TI.getWIntType(), TI, Builder); - DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Builder); - DefineTypeSize("__SIZE_MAX__", TI.getSizeType(), TI, Builder); + DefineTypeSizeAndWidth("__WCHAR", TI.getWCharType(), TI, Builder); + DefineTypeSizeAndWidth("__WINT", TI.getWIntType(), TI, Builder); + DefineTypeSizeAndWidth("__INTMAX", TI.getIntMaxType(), TI, Builder); + DefineTypeSizeAndWidth("__SIZE", TI.getSizeType(), TI, Builder); - DefineTypeSize("__UINTMAX_MAX__", TI.getUIntMaxType(), TI, Builder); - DefineTypeSize("__PTRDIFF_MAX__", TI.getPtrDiffType(0), TI, Builder); - DefineTypeSize("__INTPTR_MAX__", TI.getIntPtrType(), TI, Builder); - DefineTypeSize("__UINTPTR_MAX__", TI.getUIntPtrType(), TI, Builder); + DefineTypeSizeAndWidth("__UINTMAX", TI.getUIntMaxType(), TI, Builder); + DefineTypeSizeAndWidth("__PTRDIFF", TI.getPtrDiffType(0), TI, Builder); + DefineTypeSizeAndWidth("__INTPTR", TI.getIntPtrType(), TI, Builder); + DefineTypeSizeAndWidth("__UINTPTR", TI.getUIntPtrType(), TI, Builder); DefineTypeSizeof("__SIZEOF_DOUBLE__", TI.getDoubleWidth(), TI, Builder); DefineTypeSizeof("__SIZEOF_FLOAT__", TI.getFloatWidth(), TI, Builder); @@ -929,29 +956,29 @@ static void InitializePredefinedMacros(const TargetInfo &TI, DefineFmt("__UINTMAX", TI.getUIntMaxType(), TI, Builder); Builder.defineMacro("__UINTMAX_C_SUFFIX__", TI.getTypeConstantSuffix(TI.getUIntMaxType())); - DefineTypeWidth("__INTMAX_WIDTH__", TI.getIntMaxType(), TI, Builder); DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(0), Builder); DefineFmt("__PTRDIFF", TI.getPtrDiffType(0), TI, Builder); - DefineTypeWidth("__PTRDIFF_WIDTH__", TI.getPtrDiffType(0), TI, Builder); DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder); DefineFmt("__INTPTR", TI.getIntPtrType(), TI, Builder); - DefineTypeWidth("__INTPTR_WIDTH__", TI.getIntPtrType(), TI, Builder); DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder); DefineFmt("__SIZE", TI.getSizeType(), TI, Builder); - DefineTypeWidth("__SIZE_WIDTH__", TI.getSizeType(), TI, Builder); DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder); - DefineTypeWidth("__WCHAR_WIDTH__", TI.getWCharType(), TI, Builder); DefineType("__WINT_TYPE__", TI.getWIntType(), Builder); - DefineTypeWidth("__WINT_WIDTH__", TI.getWIntType(), TI, Builder); - DefineTypeWidth("__SIG_ATOMIC_WIDTH__", TI.getSigAtomicType(), TI, Builder); - DefineTypeSize("__SIG_ATOMIC_MAX__", TI.getSigAtomicType(), TI, Builder); + DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder); DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder); DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder); - DefineTypeWidth("__UINTMAX_WIDTH__", TI.getUIntMaxType(), TI, Builder); DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder); DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder); - DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder); + + // The C standard requires the width of uintptr_t and intptr_t to be the same, + // per 7.20.2.4p1. Same for intmax_t and uintmax_t, per 7.20.2.5p1. + assert(TI.getTypeWidth(TI.getUIntPtrType()) == + TI.getTypeWidth(TI.getIntPtrType()) && + "uintptr_t and intptr_t have different widths?"); + assert(TI.getTypeWidth(TI.getUIntMaxType()) == + TI.getTypeWidth(TI.getIntMaxType()) && + "uintmax_t and intmax_t have different widths?"); if (TI.hasFloat16Type()) DefineFloatMacros(Builder, "FLT16", &TI.getHalfFormat(), "F16"); @@ -1039,6 +1066,9 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__USER_LABEL_PREFIX__", TI.getUserLabelPrefix()); + if (!LangOpts.MathErrno) + Builder.defineMacro("__NO_MATH_ERRNO__"); + if (LangOpts.FastMath || LangOpts.FiniteMathOnly) Builder.defineMacro("__FINITE_MATH_ONLY__", "1"); else diff --git contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp index 5abbb3a235b4..34bbc365e647 100644 --- contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp +++ contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp @@ -236,10 +236,10 @@ void MultiplexASTMutationListener::AddedAttributeToRecord( MultiplexConsumer::MultiplexConsumer( std::vector<std::unique_ptr<ASTConsumer>> C) - : Consumers(std::move(C)), MutationListener(), DeserializationListener() { + : Consumers(std::move(C)) { // Collect the mutation listeners and deserialization listeners of all // children, and create a multiplex listener each if so. - std::vector<ASTMutationListener*> mutationListeners; + std::vector<ASTMutationListener *> mutationListeners; std::vector<ASTDeserializationListener*> serializationListeners; for (auto &Consumer : Consumers) { if (auto *mutationListener = Consumer->GetASTMutationListener()) diff --git contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 45df86ef91cd..1d0022bda474 100644 --- contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -792,7 +792,7 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, bool IsStartOfLine = false; char Buffer[256]; - while (1) { + while (true) { // Two lines joined with line continuation ('\' as last character on the // line) must be emitted as one line even though Tok.getLine() returns two // different values. In this situation Tok.isAtStartOfLine() is false even diff --git contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp index 3f2a78127477..3e8d582f90c2 100644 --- contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -14,7 +14,6 @@ #include "clang/Rewrite/Frontend/Rewriters.h" #include "clang/Basic/SourceManager.h" #include "clang/Frontend/PreprocessorOutputOptions.h" -#include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Pragma.h" #include "clang/Lex/Preprocessor.h" #include "llvm/ADT/SmallString.h" @@ -31,10 +30,8 @@ class InclusionRewriter : public PPCallbacks { struct IncludedFile { FileID Id; SrcMgr::CharacteristicKind FileType; - const DirectoryLookup *DirLookup; - IncludedFile(FileID Id, SrcMgr::CharacteristicKind FileType, - const DirectoryLookup *DirLookup) - : Id(Id), FileType(FileType), DirLookup(DirLookup) {} + IncludedFile(FileID Id, SrcMgr::CharacteristicKind FileType) + : Id(Id), FileType(FileType) {} }; Preprocessor &PP; ///< Used to find inclusion directives. SourceManager &SM; ///< Used to read and manage source files. @@ -57,8 +54,7 @@ class InclusionRewriter : public PPCallbacks { public: InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers, bool UseLineDirectives); - void Process(FileID FileId, SrcMgr::CharacteristicKind FileType, - const DirectoryLookup *DirLookup); + void Process(FileID FileId, SrcMgr::CharacteristicKind FileType); void setPredefinesBuffer(const llvm::MemoryBufferRef &Buf) { PredefinesBuffer = Buf; } @@ -162,8 +158,7 @@ void InclusionRewriter::FileChanged(SourceLocation Loc, return; FileID Id = FullSourceLoc(Loc, SM).getFileID(); auto P = FileIncludes.insert( - std::make_pair(LastInclusionLocation, - IncludedFile(Id, NewFileType, PP.GetCurDirLookup()))); + std::make_pair(LastInclusionLocation, IncludedFile(Id, NewFileType))); (void)P; assert(P.second && "Unexpected revisitation of the same include directive"); LastInclusionLocation = SourceLocation(); @@ -256,28 +251,12 @@ bool InclusionRewriter::IsIfAtLocationTrue(SourceLocation Loc) const { return false; } -/// Detect the likely line ending style of \p FromFile by examining the first -/// newline found within it. -static StringRef DetectEOL(const MemoryBufferRef &FromFile) { - // Detect what line endings the file uses, so that added content does not mix - // the style. We need to check for "\r\n" first because "\n\r" will match - // "\r\n\r\n". - const char *Pos = strchr(FromFile.getBufferStart(), '\n'); - if (!Pos) - return "\n"; - if (Pos - 1 >= FromFile.getBufferStart() && Pos[-1] == '\r') - return "\r\n"; - if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r') - return "\n\r"; - return "\n"; -} - void InclusionRewriter::detectMainFileEOL() { Optional<MemoryBufferRef> FromFile = *SM.getBufferOrNone(SM.getMainFileID()); assert(FromFile); if (!FromFile) return; // Should never happen, but whatever. - MainEOL = DetectEOL(*FromFile); + MainEOL = FromFile->getBuffer().detectEOL(); } /// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at @@ -371,8 +350,7 @@ StringRef InclusionRewriter::NextIdentifierName(Lexer &RawLex, /// Use a raw lexer to analyze \p FileId, incrementally copying parts of it /// and including content of included files recursively. void InclusionRewriter::Process(FileID FileId, - SrcMgr::CharacteristicKind FileType, - const DirectoryLookup *DirLookup) { + SrcMgr::CharacteristicKind FileType) { MemoryBufferRef FromFile; { auto B = SM.getBufferOrNone(FileId); @@ -384,7 +362,7 @@ void InclusionRewriter::Process(FileID FileId, Lexer RawLex(FileId, FromFile, PP.getSourceManager(), PP.getLangOpts()); RawLex.SetCommentRetentionState(false); - StringRef LocalEOL = DetectEOL(FromFile); + StringRef LocalEOL = FromFile.getBuffer().detectEOL(); // Per the GNU docs: "1" indicates entering a new file. if (FileId == SM.getMainFileID() || FileId == PP.getPredefinesFileID()) @@ -433,7 +411,7 @@ void InclusionRewriter::Process(FileID FileId, << Mod->getFullModuleName(true) << "\n"; // Include and recursively process the file. - Process(Inc->Id, Inc->FileType, Inc->DirLookup); + Process(Inc->Id, Inc->FileType); if (Mod) OS << "#pragma clang module end /*" @@ -559,7 +537,7 @@ void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS, Rewrite->handleModuleBegin(Tok); } while (Tok.isNot(tok::eof)); Rewrite->setPredefinesBuffer(SM.getBufferOrFake(PP.getPredefinesFileID())); - Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User, nullptr); - Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User, nullptr); + Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User); + Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User); OS->flush(); } diff --git contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp index 462aeda6e027..fc8fce4b42b8 100644 --- contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -95,8 +95,7 @@ class SDiagsMerger : SerializedDiagnosticReader { AbbrevLookup DiagFlagLookup; public: - SDiagsMerger(SDiagsWriter &Writer) - : SerializedDiagnosticReader(), Writer(Writer) {} + SDiagsMerger(SDiagsWriter &Writer) : Writer(Writer) {} std::error_code mergeRecordsFromFile(const char *File) { return readDiagnostics(File); diff --git contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp index 8df7496c6ddd..1c4a76e68953 100644 --- contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp +++ contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp @@ -44,7 +44,7 @@ static const enum raw_ostream::Colors savedColor = /// Add highlights to differences in template strings. static void applyTemplateHighlighting(raw_ostream &OS, StringRef Str, bool &Normal, bool Bold) { - while (1) { + while (true) { size_t Pos = Str.find(ToggleHighlight); OS << Str.slice(0, Pos); if (Pos == StringRef::npos) diff --git contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp index 2759625ae254..f67dceea9135 100644 --- contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -541,9 +541,8 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, ExpectedLoc = SourceLocation(); } else { // Lookup file via Preprocessor, like a #include. - const DirectoryLookup *CurDir; Optional<FileEntryRef> File = - PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir, + PP->LookupFile(Pos, Filename, false, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (!File) { Diags.Report(Pos.getLocWithOffset(PH.C - PH.Begin), diff --git contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 8e18f33af0cb..8a8a13743762 100644 --- contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -57,6 +57,8 @@ CreateFrontendBaseAction(CompilerInstance &CI) { case EmitLLVMOnly: return std::make_unique<EmitLLVMOnlyAction>(); case EmitCodeGenOnly: return std::make_unique<EmitCodeGenOnlyAction>(); case EmitObj: return std::make_unique<EmitObjAction>(); + case ExtractAPI: + return std::make_unique<ExtractAPIAction>(); case FixIt: return std::make_unique<FixItAction>(); case GenerateModule: return std::make_unique<GenerateModuleFromModuleMapAction>(); diff --git contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h index 538556f394da..e447590393ec 100644 --- contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h +++ contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h @@ -345,4 +345,4 @@ __DEVICE__ float ynf(int __a, float __b) { return __nv_ynf(__a, __b); } #pragma pop_macro("__DEVICE_VOID__") #pragma pop_macro("__FAST_OR_SLOW") -#endif // __CLANG_CUDA_DEVICE_FUNCTIONS_H__ +#endif // __CLANG_CUDA_MATH_H__ diff --git contrib/llvm-project/clang/lib/Headers/__clang_hip_runtime_wrapper.h contrib/llvm-project/clang/lib/Headers/__clang_hip_runtime_wrapper.h index 73021d256cba..10cec58ed12f 100644 --- contrib/llvm-project/clang/lib/Headers/__clang_hip_runtime_wrapper.h +++ contrib/llvm-project/clang/lib/Headers/__clang_hip_runtime_wrapper.h @@ -50,6 +50,9 @@ extern "C" { #include <cmath> #include <cstdlib> #include <stdlib.h> +#if __has_include("hip/hip_version.h") +#include "hip/hip_version.h" +#endif // __has_include("hip/hip_version.h") #else typedef __SIZE_TYPE__ size_t; // Define macros which are needed to declare HIP device API's without standard @@ -74,25 +77,35 @@ typedef __SIZE_TYPE__ __hip_size_t; extern "C" { #endif //__cplusplus +#if HIP_VERSION_MAJOR * 100 + HIP_VERSION_MINOR >= 405 +extern "C" __device__ unsigned long long __ockl_dm_alloc(unsigned long long __size); +extern "C" __device__ void __ockl_dm_dealloc(unsigned long long __addr); +__attribute__((weak)) inline __device__ void *malloc(__hip_size_t __size) { + return (void *) __ockl_dm_alloc(__size); +} +__attribute__((weak)) inline __device__ void free(void *__ptr) { + __ockl_dm_dealloc((unsigned long long)__ptr); +} +#else // HIP version check #if __HIP_ENABLE_DEVICE_MALLOC__ __device__ void *__hip_malloc(__hip_size_t __size); __device__ void *__hip_free(void *__ptr); __attribute__((weak)) inline __device__ void *malloc(__hip_size_t __size) { return __hip_malloc(__size); } -__attribute__((weak)) inline __device__ void *free(void *__ptr) { - return __hip_free(__ptr); +__attribute__((weak)) inline __device__ void free(void *__ptr) { + __hip_free(__ptr); } #else __attribute__((weak)) inline __device__ void *malloc(__hip_size_t __size) { __builtin_trap(); return (void *)0; } -__attribute__((weak)) inline __device__ void *free(void *__ptr) { +__attribute__((weak)) inline __device__ void free(void *__ptr) { __builtin_trap(); - return (void *)0; } #endif +#endif // HIP version check #ifdef __cplusplus } // extern "C" diff --git contrib/llvm-project/clang/lib/Headers/avx2intrin.h contrib/llvm-project/clang/lib/Headers/avx2intrin.h index 5064c87c2bb1..e33514a60ff3 100644 --- contrib/llvm-project/clang/lib/Headers/avx2intrin.h +++ contrib/llvm-project/clang/lib/Headers/avx2intrin.h @@ -26,19 +26,19 @@ static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_abs_epi8(__m256i __a) { - return (__m256i)__builtin_ia32_pabsb256((__v32qi)__a); + return (__m256i)__builtin_elementwise_abs((__v32qs)__a); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_abs_epi16(__m256i __a) { - return (__m256i)__builtin_ia32_pabsw256((__v16hi)__a); + return (__m256i)__builtin_elementwise_abs((__v16hi)__a); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_abs_epi32(__m256i __a) { - return (__m256i)__builtin_ia32_pabsd256((__v8si)__a); + return (__m256i)__builtin_elementwise_abs((__v8si)__a); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 @@ -253,73 +253,73 @@ _mm256_madd_epi16(__m256i __a, __m256i __b) static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_max_epi8(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pmaxsb256((__v32qi)__a, (__v32qi)__b); + return (__m256i)__builtin_elementwise_max((__v32qs)__a, (__v32qs)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_max_epi16(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pmaxsw256((__v16hi)__a, (__v16hi)__b); + return (__m256i)__builtin_elementwise_max((__v16hi)__a, (__v16hi)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_max_epi32(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pmaxsd256((__v8si)__a, (__v8si)__b); + return (__m256i)__builtin_elementwise_max((__v8si)__a, (__v8si)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_max_epu8(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pmaxub256((__v32qi)__a, (__v32qi)__b); + return (__m256i)__builtin_elementwise_max((__v32qu)__a, (__v32qu)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_max_epu16(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pmaxuw256((__v16hi)__a, (__v16hi)__b); + return (__m256i)__builtin_elementwise_max((__v16hu)__a, (__v16hu)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_max_epu32(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pmaxud256((__v8si)__a, (__v8si)__b); + return (__m256i)__builtin_elementwise_max((__v8su)__a, (__v8su)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_min_epi8(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pminsb256((__v32qi)__a, (__v32qi)__b); + return (__m256i)__builtin_elementwise_min((__v32qs)__a, (__v32qs)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_min_epi16(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pminsw256((__v16hi)__a, (__v16hi)__b); + return (__m256i)__builtin_elementwise_min((__v16hi)__a, (__v16hi)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_min_epi32(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pminsd256((__v8si)__a, (__v8si)__b); + return (__m256i)__builtin_elementwise_min((__v8si)__a, (__v8si)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_min_epu8(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pminub256((__v32qi)__a, (__v32qi)__b); + return (__m256i)__builtin_elementwise_min((__v32qu)__a, (__v32qu)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_min_epu16(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pminuw256 ((__v16hi)__a, (__v16hi)__b); + return (__m256i)__builtin_elementwise_min((__v16hu)__a, (__v16hu)__b); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_min_epu32(__m256i __a, __m256i __b) { - return (__m256i)__builtin_ia32_pminud256((__v8si)__a, (__v8si)__b); + return (__m256i)__builtin_elementwise_min((__v8su)__a, (__v8su)__b); } static __inline__ int __DEFAULT_FN_ATTRS256 diff --git contrib/llvm-project/clang/lib/Headers/avx512bwintrin.h contrib/llvm-project/clang/lib/Headers/avx512bwintrin.h index 6aee8aed8487..522ef100bab1 100644 --- contrib/llvm-project/clang/lib/Headers/avx512bwintrin.h +++ contrib/llvm-project/clang/lib/Headers/avx512bwintrin.h @@ -485,7 +485,7 @@ _mm512_mask_blend_epi16 (__mmask32 __U, __m512i __A, __m512i __W) static __inline__ __m512i __DEFAULT_FN_ATTRS512 _mm512_abs_epi8 (__m512i __A) { - return (__m512i)__builtin_ia32_pabsb512((__v64qi)__A); + return (__m512i)__builtin_elementwise_abs((__v64qs)__A); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -507,7 +507,7 @@ _mm512_maskz_abs_epi8 (__mmask64 __U, __m512i __A) static __inline__ __m512i __DEFAULT_FN_ATTRS512 _mm512_abs_epi16 (__m512i __A) { - return (__m512i)__builtin_ia32_pabsw512((__v32hi)__A); + return (__m512i)__builtin_elementwise_abs((__v32hi)__A); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -751,7 +751,7 @@ _mm512_maskz_avg_epu16 (__mmask32 __U, __m512i __A, __m512i __B) static __inline__ __m512i __DEFAULT_FN_ATTRS512 _mm512_max_epi8 (__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pmaxsb512((__v64qi) __A, (__v64qi) __B); + return (__m512i)__builtin_elementwise_max((__v64qs) __A, (__v64qs) __B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -773,7 +773,7 @@ _mm512_mask_max_epi8 (__m512i __W, __mmask64 __M, __m512i __A, __m512i __B) static __inline__ __m512i __DEFAULT_FN_ATTRS512 _mm512_max_epi16 (__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pmaxsw512((__v32hi) __A, (__v32hi) __B); + return (__m512i)__builtin_elementwise_max((__v32hi) __A, (__v32hi) __B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -796,7 +796,7 @@ _mm512_mask_max_epi16 (__m512i __W, __mmask32 __M, __m512i __A, static __inline__ __m512i __DEFAULT_FN_ATTRS512 _mm512_max_epu8 (__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pmaxub512((__v64qi)__A, (__v64qi)__B); + return (__m512i)__builtin_elementwise_max((__v64qu)__A, (__v64qu)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -818,7 +818,7 @@ _mm512_mask_max_epu8 (__m512i __W, __mmask64 __M, __m512i __A, __m512i __B) static __inline__ __m512i __DEFAULT_FN_ATTRS512 _mm512_max_epu16 (__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pmaxuw512((__v32hi)__A, (__v32hi)__B); + return (__m512i)__builtin_elementwise_max((__v32hu)__A, (__v32hu)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -840,7 +840,7 @@ _mm512_mask_max_epu16 (__m512i __W, __mmask32 __M, __m512i __A, __m512i __B) static __inline__ __m512i __DEFAULT_FN_ATTRS512 _mm512_min_epi8 (__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pminsb512((__v64qi) __A, (__v64qi) __B); + return (__m512i)__builtin_elementwise_min((__v64qs) __A, (__v64qs) __B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -862,7 +862,7 @@ _mm512_mask_min_epi8 (__m512i __W, __mmask64 __M, __m512i __A, __m512i __B) static __inline__ __m512i __DEFAULT_FN_ATTRS512 _mm512_min_epi16 (__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pminsw512((__v32hi) __A, (__v32hi) __B); + return (__m512i)__builtin_elementwise_min((__v32hi) __A, (__v32hi) __B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -884,7 +884,7 @@ _mm512_mask_min_epi16 (__m512i __W, __mmask32 __M, __m512i __A, __m512i __B) static __inline__ __m512i __DEFAULT_FN_ATTRS512 _mm512_min_epu8 (__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pminub512((__v64qi)__A, (__v64qi)__B); + return (__m512i)__builtin_elementwise_min((__v64qu)__A, (__v64qu)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -906,7 +906,7 @@ _mm512_mask_min_epu8 (__m512i __W, __mmask64 __M, __m512i __A, __m512i __B) static __inline__ __m512i __DEFAULT_FN_ATTRS512 _mm512_min_epu16 (__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pminuw512((__v32hi)__A, (__v32hi)__B); + return (__m512i)__builtin_elementwise_min((__v32hu)__A, (__v32hu)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 diff --git contrib/llvm-project/clang/lib/Headers/avx512fintrin.h contrib/llvm-project/clang/lib/Headers/avx512fintrin.h index df298640523b..50e0e287d9fc 100644 --- contrib/llvm-project/clang/lib/Headers/avx512fintrin.h +++ contrib/llvm-project/clang/lib/Headers/avx512fintrin.h @@ -26,6 +26,10 @@ typedef unsigned short __v32hu __attribute__((__vector_size__(64))); typedef unsigned long long __v8du __attribute__((__vector_size__(64))); typedef unsigned int __v16su __attribute__((__vector_size__(64))); +/* We need an explicitly signed variant for char. Note that this shouldn't + * appear in the interface though. */ +typedef signed char __v64qs __attribute__((__vector_size__(64))); + typedef float __m512 __attribute__((__vector_size__(64), __aligned__(64))); typedef double __m512d __attribute__((__vector_size__(64), __aligned__(64))); typedef long long __m512i __attribute__((__vector_size__(64), __aligned__(64))); @@ -1086,7 +1090,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512 _mm512_max_epi32(__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pmaxsd512((__v16si)__A, (__v16si)__B); + return (__m512i)__builtin_elementwise_max((__v16si)__A, (__v16si)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -1108,7 +1112,7 @@ _mm512_maskz_max_epi32 (__mmask16 __M, __m512i __A, __m512i __B) static __inline __m512i __DEFAULT_FN_ATTRS512 _mm512_max_epu32(__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pmaxud512((__v16si)__A, (__v16si)__B); + return (__m512i)__builtin_elementwise_max((__v16su)__A, (__v16su)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -1130,7 +1134,7 @@ _mm512_maskz_max_epu32 (__mmask16 __M, __m512i __A, __m512i __B) static __inline __m512i __DEFAULT_FN_ATTRS512 _mm512_max_epi64(__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pmaxsq512((__v8di)__A, (__v8di)__B); + return (__m512i)__builtin_elementwise_max((__v8di)__A, (__v8di)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -1152,7 +1156,7 @@ _mm512_maskz_max_epi64 (__mmask8 __M, __m512i __A, __m512i __B) static __inline __m512i __DEFAULT_FN_ATTRS512 _mm512_max_epu64(__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pmaxuq512((__v8di)__A, (__v8di)__B); + return (__m512i)__builtin_elementwise_max((__v8du)__A, (__v8du)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -1321,7 +1325,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512 _mm512_min_epi32(__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pminsd512((__v16si)__A, (__v16si)__B); + return (__m512i)__builtin_elementwise_min((__v16si)__A, (__v16si)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -1343,7 +1347,7 @@ _mm512_maskz_min_epi32 (__mmask16 __M, __m512i __A, __m512i __B) static __inline __m512i __DEFAULT_FN_ATTRS512 _mm512_min_epu32(__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pminud512((__v16si)__A, (__v16si)__B); + return (__m512i)__builtin_elementwise_min((__v16su)__A, (__v16su)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -1365,7 +1369,7 @@ _mm512_maskz_min_epu32 (__mmask16 __M, __m512i __A, __m512i __B) static __inline __m512i __DEFAULT_FN_ATTRS512 _mm512_min_epi64(__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pminsq512((__v8di)__A, (__v8di)__B); + return (__m512i)__builtin_elementwise_min((__v8di)__A, (__v8di)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -1387,7 +1391,7 @@ _mm512_maskz_min_epi64 (__mmask8 __M, __m512i __A, __m512i __B) static __inline __m512i __DEFAULT_FN_ATTRS512 _mm512_min_epu64(__m512i __A, __m512i __B) { - return (__m512i)__builtin_ia32_pminuq512((__v8di)__A, (__v8di)__B); + return (__m512i)__builtin_elementwise_min((__v8du)__A, (__v8du)__B); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -1846,7 +1850,7 @@ _mm512_mask_ceil_pd (__m512d __W, __mmask8 __U, __m512d __A) static __inline __m512i __DEFAULT_FN_ATTRS512 _mm512_abs_epi64(__m512i __A) { - return (__m512i)__builtin_ia32_pabsq512((__v8di)__A); + return (__m512i)__builtin_elementwise_abs((__v8di)__A); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -1868,7 +1872,7 @@ _mm512_maskz_abs_epi64 (__mmask8 __U, __m512i __A) static __inline __m512i __DEFAULT_FN_ATTRS512 _mm512_abs_epi32(__m512i __A) { - return (__m512i)__builtin_ia32_pabsd512((__v16si) __A); + return (__m512i)__builtin_elementwise_abs((__v16si) __A); } static __inline__ __m512i __DEFAULT_FN_ATTRS512 @@ -9320,11 +9324,11 @@ static __inline__ long long __DEFAULT_FN_ATTRS512 _mm512_reduce_mul_epi64(__m512 } static __inline__ long long __DEFAULT_FN_ATTRS512 _mm512_reduce_and_epi64(__m512i __W) { - return __builtin_ia32_reduce_and_q512(__W); + return __builtin_reduce_and((__v8di)__W); } static __inline__ long long __DEFAULT_FN_ATTRS512 _mm512_reduce_or_epi64(__m512i __W) { - return __builtin_ia32_reduce_or_q512(__W); + return __builtin_reduce_or((__v8di)__W); } static __inline__ long long __DEFAULT_FN_ATTRS512 @@ -9342,13 +9346,13 @@ _mm512_mask_reduce_mul_epi64(__mmask8 __M, __m512i __W) { static __inline__ long long __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_and_epi64(__mmask8 __M, __m512i __W) { __W = _mm512_mask_mov_epi64(_mm512_set1_epi64(~0ULL), __M, __W); - return __builtin_ia32_reduce_and_q512(__W); + return __builtin_reduce_and((__v8di)__W); } static __inline__ long long __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_or_epi64(__mmask8 __M, __m512i __W) { __W = _mm512_maskz_mov_epi64(__M, __W); - return __builtin_ia32_reduce_or_q512(__W); + return __builtin_reduce_or((__v8di)__W); } // -0.0 is used to ignore the start value since it is the neutral value of @@ -9386,12 +9390,12 @@ _mm512_reduce_mul_epi32(__m512i __W) { static __inline__ int __DEFAULT_FN_ATTRS512 _mm512_reduce_and_epi32(__m512i __W) { - return __builtin_ia32_reduce_and_d512((__v16si)__W); + return __builtin_reduce_and((__v16si)__W); } static __inline__ int __DEFAULT_FN_ATTRS512 _mm512_reduce_or_epi32(__m512i __W) { - return __builtin_ia32_reduce_or_d512((__v16si)__W); + return __builtin_reduce_or((__v16si)__W); } static __inline__ int __DEFAULT_FN_ATTRS512 @@ -9409,13 +9413,13 @@ _mm512_mask_reduce_mul_epi32( __mmask16 __M, __m512i __W) { static __inline__ int __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_and_epi32( __mmask16 __M, __m512i __W) { __W = _mm512_mask_mov_epi32(_mm512_set1_epi32(~0U), __M, __W); - return __builtin_ia32_reduce_and_d512((__v16si)__W); + return __builtin_reduce_and((__v16si)__W); } static __inline__ int __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_or_epi32(__mmask16 __M, __m512i __W) { __W = _mm512_maskz_mov_epi32(__M, __W); - return __builtin_ia32_reduce_or_d512((__v16si)__W); + return __builtin_reduce_or((__v16si)__W); } static __inline__ float __DEFAULT_FN_ATTRS512 @@ -9442,89 +9446,89 @@ _mm512_mask_reduce_mul_ps(__mmask16 __M, __m512 __W) { static __inline__ long long __DEFAULT_FN_ATTRS512 _mm512_reduce_max_epi64(__m512i __V) { - return __builtin_ia32_reduce_smax_q512(__V); + return __builtin_reduce_max((__v8di)__V); } static __inline__ unsigned long long __DEFAULT_FN_ATTRS512 _mm512_reduce_max_epu64(__m512i __V) { - return __builtin_ia32_reduce_umax_q512(__V); + return __builtin_reduce_max((__v8du)__V); } static __inline__ long long __DEFAULT_FN_ATTRS512 _mm512_reduce_min_epi64(__m512i __V) { - return __builtin_ia32_reduce_smin_q512(__V); + return __builtin_reduce_min((__v8di)__V); } static __inline__ unsigned long long __DEFAULT_FN_ATTRS512 _mm512_reduce_min_epu64(__m512i __V) { - return __builtin_ia32_reduce_umin_q512(__V); + return __builtin_reduce_min((__v8du)__V); } static __inline__ long long __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_max_epi64(__mmask8 __M, __m512i __V) { __V = _mm512_mask_mov_epi64(_mm512_set1_epi64(-__LONG_LONG_MAX__ - 1LL), __M, __V); - return __builtin_ia32_reduce_smax_q512(__V); + return __builtin_reduce_max((__v8di)__V); } static __inline__ unsigned long long __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_max_epu64(__mmask8 __M, __m512i __V) { __V = _mm512_maskz_mov_epi64(__M, __V); - return __builtin_ia32_reduce_umax_q512(__V); + return __builtin_reduce_max((__v8du)__V); } static __inline__ long long __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_min_epi64(__mmask8 __M, __m512i __V) { __V = _mm512_mask_mov_epi64(_mm512_set1_epi64(__LONG_LONG_MAX__), __M, __V); - return __builtin_ia32_reduce_smin_q512(__V); + return __builtin_reduce_min((__v8di)__V); } static __inline__ unsigned long long __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_min_epu64(__mmask8 __M, __m512i __V) { __V = _mm512_mask_mov_epi64(_mm512_set1_epi64(~0ULL), __M, __V); - return __builtin_ia32_reduce_umin_q512(__V); + return __builtin_reduce_min((__v8du)__V); } static __inline__ int __DEFAULT_FN_ATTRS512 _mm512_reduce_max_epi32(__m512i __V) { - return __builtin_ia32_reduce_smax_d512((__v16si)__V); + return __builtin_reduce_max((__v16si)__V); } static __inline__ unsigned int __DEFAULT_FN_ATTRS512 _mm512_reduce_max_epu32(__m512i __V) { - return __builtin_ia32_reduce_umax_d512((__v16si)__V); + return __builtin_reduce_max((__v16su)__V); } static __inline__ int __DEFAULT_FN_ATTRS512 _mm512_reduce_min_epi32(__m512i __V) { - return __builtin_ia32_reduce_smin_d512((__v16si)__V); + return __builtin_reduce_min((__v16si)__V); } static __inline__ unsigned int __DEFAULT_FN_ATTRS512 _mm512_reduce_min_epu32(__m512i __V) { - return __builtin_ia32_reduce_umin_d512((__v16si)__V); + return __builtin_reduce_min((__v16su)__V); } static __inline__ int __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_max_epi32(__mmask16 __M, __m512i __V) { __V = _mm512_mask_mov_epi32(_mm512_set1_epi32(-__INT_MAX__ - 1), __M, __V); - return __builtin_ia32_reduce_smax_d512((__v16si)__V); + return __builtin_reduce_max((__v16si)__V); } static __inline__ unsigned int __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_max_epu32(__mmask16 __M, __m512i __V) { __V = _mm512_maskz_mov_epi32(__M, __V); - return __builtin_ia32_reduce_umax_d512((__v16si)__V); + return __builtin_reduce_max((__v16su)__V); } static __inline__ int __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_min_epi32(__mmask16 __M, __m512i __V) { __V = _mm512_mask_mov_epi32(_mm512_set1_epi32(__INT_MAX__), __M, __V); - return __builtin_ia32_reduce_smin_d512((__v16si)__V); + return __builtin_reduce_min((__v16si)__V); } static __inline__ unsigned int __DEFAULT_FN_ATTRS512 _mm512_mask_reduce_min_epu32(__mmask16 __M, __m512i __V) { __V = _mm512_mask_mov_epi32(_mm512_set1_epi32(~0U), __M, __V); - return __builtin_ia32_reduce_umin_d512((__v16si)__V); + return __builtin_reduce_min((__v16su)__V); } static __inline__ double __DEFAULT_FN_ATTRS512 diff --git contrib/llvm-project/clang/lib/Headers/avx512vlintrin.h contrib/llvm-project/clang/lib/Headers/avx512vlintrin.h index 0519dba59081..178c9dbc0e6e 100644 --- contrib/llvm-project/clang/lib/Headers/avx512vlintrin.h +++ contrib/llvm-project/clang/lib/Headers/avx512vlintrin.h @@ -2988,7 +2988,7 @@ _mm256_maskz_abs_epi32(__mmask8 __U, __m256i __A) { static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_abs_epi64 (__m128i __A) { - return (__m128i)__builtin_ia32_pabsq128((__v2di)__A); + return (__m128i)__builtin_elementwise_abs((__v2di)__A); } static __inline__ __m128i __DEFAULT_FN_ATTRS128 @@ -3007,7 +3007,7 @@ _mm_maskz_abs_epi64 (__mmask8 __U, __m128i __A) { static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_abs_epi64 (__m256i __A) { - return (__m256i)__builtin_ia32_pabsq256 ((__v4di)__A); + return (__m256i)__builtin_elementwise_abs((__v4di)__A); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 @@ -3054,7 +3054,7 @@ _mm256_mask_max_epi32(__m256i __W, __mmask8 __M, __m256i __A, __m256i __B) { static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_max_epi64 (__m128i __A, __m128i __B) { - return (__m128i)__builtin_ia32_pmaxsq128((__v2di)__A, (__v2di)__B); + return (__m128i)__builtin_elementwise_max((__v2di)__A, (__v2di)__B); } static __inline__ __m128i __DEFAULT_FN_ATTRS128 @@ -3073,7 +3073,7 @@ _mm_mask_max_epi64 (__m128i __W, __mmask8 __M, __m128i __A, __m128i __B) { static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_max_epi64 (__m256i __A, __m256i __B) { - return (__m256i)__builtin_ia32_pmaxsq256((__v4di)__A, (__v4di)__B); + return (__m256i)__builtin_elementwise_max((__v4di)__A, (__v4di)__B); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 @@ -3120,7 +3120,7 @@ _mm256_mask_max_epu32(__m256i __W, __mmask8 __M, __m256i __A, __m256i __B) { static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_max_epu64 (__m128i __A, __m128i __B) { - return (__m128i)__builtin_ia32_pmaxuq128((__v2di)__A, (__v2di)__B); + return (__m128i)__builtin_elementwise_max((__v2du)__A, (__v2du)__B); } static __inline__ __m128i __DEFAULT_FN_ATTRS128 @@ -3139,7 +3139,7 @@ _mm_mask_max_epu64 (__m128i __W, __mmask8 __M, __m128i __A, __m128i __B) { static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_max_epu64 (__m256i __A, __m256i __B) { - return (__m256i)__builtin_ia32_pmaxuq256((__v4di)__A, (__v4di)__B); + return (__m256i)__builtin_elementwise_max((__v4du)__A, (__v4du)__B); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 @@ -3186,7 +3186,7 @@ _mm256_mask_min_epi32(__m256i __W, __mmask8 __M, __m256i __A, __m256i __B) { static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_min_epi64 (__m128i __A, __m128i __B) { - return (__m128i)__builtin_ia32_pminsq128((__v2di)__A, (__v2di)__B); + return (__m128i)__builtin_elementwise_min((__v2di)__A, (__v2di)__B); } static __inline__ __m128i __DEFAULT_FN_ATTRS128 @@ -3205,7 +3205,7 @@ _mm_maskz_min_epi64 (__mmask8 __M, __m128i __A, __m128i __B) { static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_min_epi64 (__m256i __A, __m256i __B) { - return (__m256i)__builtin_ia32_pminsq256((__v4di)__A, (__v4di)__B); + return (__m256i)__builtin_elementwise_min((__v4di)__A, (__v4di)__B); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 @@ -3252,7 +3252,7 @@ _mm256_mask_min_epu32(__m256i __W, __mmask8 __M, __m256i __A, __m256i __B) { static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_min_epu64 (__m128i __A, __m128i __B) { - return (__m128i)__builtin_ia32_pminuq128((__v2di)__A, (__v2di)__B); + return (__m128i)__builtin_elementwise_min((__v2du)__A, (__v2du)__B); } static __inline__ __m128i __DEFAULT_FN_ATTRS128 @@ -3271,7 +3271,7 @@ _mm_maskz_min_epu64 (__mmask8 __M, __m128i __A, __m128i __B) { static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_min_epu64 (__m256i __A, __m256i __B) { - return (__m256i)__builtin_ia32_pminuq256((__v4di)__A, (__v4di)__B); + return (__m256i)__builtin_elementwise_min((__v4du)__A, (__v4du)__B); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 diff --git contrib/llvm-project/clang/lib/Headers/cetintrin.h contrib/llvm-project/clang/lib/Headers/cetintrin.h index 4290e9d7355b..019cab0261e7 100644 --- contrib/llvm-project/clang/lib/Headers/cetintrin.h +++ contrib/llvm-project/clang/lib/Headers/cetintrin.h @@ -42,10 +42,20 @@ static __inline__ unsigned int __DEFAULT_FN_ATTRS _rdsspd(unsigned int __a) { return __builtin_ia32_rdsspd(__a); } +static __inline__ unsigned int __DEFAULT_FN_ATTRS _rdsspd_i32() { + unsigned int t; + return __builtin_ia32_rdsspd(t); +} + #ifdef __x86_64__ static __inline__ unsigned long long __DEFAULT_FN_ATTRS _rdsspq(unsigned long long __a) { return __builtin_ia32_rdsspq(__a); } + +static __inline__ unsigned long long __DEFAULT_FN_ATTRS _rdsspq_i64() { + unsigned long long t; + return __builtin_ia32_rdsspq(t); +} #endif /* __x86_64__ */ #ifdef __x86_64__ diff --git contrib/llvm-project/clang/lib/Headers/cpuid.h contrib/llvm-project/clang/lib/Headers/cpuid.h index 6df1b4a11172..5d262a60735f 100644 --- contrib/llvm-project/clang/lib/Headers/cpuid.h +++ contrib/llvm-project/clang/lib/Headers/cpuid.h @@ -200,7 +200,7 @@ #define bit_AMXINT8 0x02000000 /* Features in %eax for leaf 7 sub-leaf 1 */ -#define bit_AVXVNNI 0x00000008 +#define bit_AVXVNNI 0x00000010 #define bit_AVX512BF16 0x00000020 #define bit_HRESET 0x00400000 diff --git contrib/llvm-project/clang/lib/Headers/emmintrin.h contrib/llvm-project/clang/lib/Headers/emmintrin.h index 6e9c3032c21f..4618b808efc4 100644 --- contrib/llvm-project/clang/lib/Headers/emmintrin.h +++ contrib/llvm-project/clang/lib/Headers/emmintrin.h @@ -2375,7 +2375,7 @@ _mm_madd_epi16(__m128i __a, __m128i __b) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_max_epi16(__m128i __a, __m128i __b) { - return (__m128i)__builtin_ia32_pmaxsw128((__v8hi)__a, (__v8hi)__b); + return (__m128i)__builtin_elementwise_max((__v8hi)__a, (__v8hi)__b); } /// Compares corresponding elements of two 128-bit unsigned [16 x i8] @@ -2395,7 +2395,7 @@ _mm_max_epi16(__m128i __a, __m128i __b) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_max_epu8(__m128i __a, __m128i __b) { - return (__m128i)__builtin_ia32_pmaxub128((__v16qi)__a, (__v16qi)__b); + return (__m128i)__builtin_elementwise_max((__v16qu)__a, (__v16qu)__b); } /// Compares corresponding elements of two 128-bit signed [8 x i16] @@ -2415,7 +2415,7 @@ _mm_max_epu8(__m128i __a, __m128i __b) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_min_epi16(__m128i __a, __m128i __b) { - return (__m128i)__builtin_ia32_pminsw128((__v8hi)__a, (__v8hi)__b); + return (__m128i)__builtin_elementwise_min((__v8hi)__a, (__v8hi)__b); } /// Compares corresponding elements of two 128-bit unsigned [16 x i8] @@ -2435,7 +2435,7 @@ _mm_min_epi16(__m128i __a, __m128i __b) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_min_epu8(__m128i __a, __m128i __b) { - return (__m128i)__builtin_ia32_pminub128((__v16qi)__a, (__v16qi)__b); + return (__m128i)__builtin_elementwise_min((__v16qu)__a, (__v16qu)__b); } /// Multiplies the corresponding elements of two signed [8 x i16] diff --git contrib/llvm-project/clang/lib/Headers/limits.h contrib/llvm-project/clang/lib/Headers/limits.h index c653580bac4e..c2d3a7cf4353 100644 --- contrib/llvm-project/clang/lib/Headers/limits.h +++ contrib/llvm-project/clang/lib/Headers/limits.h @@ -62,6 +62,24 @@ #define CHAR_BIT __CHAR_BIT__ +/* C2x 5.2.4.2.1 */ +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +#define BOOL_WIDTH __BOOL_WIDTH__ +#define CHAR_WIDTH CHAR_BIT +#define SCHAR_WIDTH CHAR_BIT +#define UCHAR_WIDTH CHAR_BIT +#define USHRT_WIDTH __SHRT_WIDTH__ +#define SHRT_WIDTH __SHRT_WIDTH__ +#define UINT_WIDTH __INT_WIDTH__ +#define INT_WIDTH __INT_WIDTH__ +#define ULONG_WIDTH __LONG_WIDTH__ +#define LONG_WIDTH __LONG_WIDTH__ +#define ULLONG_WIDTH __LLONG_WIDTH__ +#define LLONG_WIDTH __LLONG_WIDTH__ +#endif + #ifdef __CHAR_UNSIGNED__ /* -funsigned-char */ #define CHAR_MIN 0 #define CHAR_MAX UCHAR_MAX diff --git contrib/llvm-project/clang/lib/Headers/opencl-c-base.h contrib/llvm-project/clang/lib/Headers/opencl-c-base.h index 9c81ddb5e2a7..06b78da63e69 100644 --- contrib/llvm-project/clang/lib/Headers/opencl-c-base.h +++ contrib/llvm-project/clang/lib/Headers/opencl-c-base.h @@ -68,6 +68,7 @@ // For the SPIR and SPIR-V target all features are supported. #if defined(__SPIR__) || defined(__SPIRV__) #define __opencl_c_atomic_scope_all_devices 1 +#define __opencl_c_read_write_images 1 #endif // defined(__SPIR__) #endif // (__OPENCL_CPP_VERSION__ == 202100 || __OPENCL_C_VERSION__ == 300) @@ -498,12 +499,14 @@ typedef int clk_profiling_info; #define MAX_WORK_DIM 3 +#ifdef __opencl_c_device_enqueue typedef struct { unsigned int workDimension; size_t globalWorkOffset[MAX_WORK_DIM]; size_t globalWorkSize[MAX_WORK_DIM]; size_t localWorkSize[MAX_WORK_DIM]; } ndrange_t; +#endif // __opencl_c_device_enqueue #endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) @@ -600,9 +603,11 @@ typedef struct { // C++ for OpenCL - __remove_address_space #if defined(__OPENCL_CPP_VERSION__) template <typename _Tp> struct __remove_address_space { using type = _Tp; }; +#if defined(__opencl_c_generic_address_space) template <typename _Tp> struct __remove_address_space<__generic _Tp> { using type = _Tp; }; +#endif template <typename _Tp> struct __remove_address_space<__global _Tp> { using type = _Tp; }; diff --git contrib/llvm-project/clang/lib/Headers/opencl-c.h contrib/llvm-project/clang/lib/Headers/opencl-c.h index 77a7a8b9bb3a..8fde2fa29899 100644 --- contrib/llvm-project/clang/lib/Headers/opencl-c.h +++ contrib/llvm-project/clang/lib/Headers/opencl-c.h @@ -11,11 +11,11 @@ #include "opencl-c-base.h" -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_images) #ifndef cl_khr_depth_images #define cl_khr_depth_images #endif //cl_khr_depth_images -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_images) #if __OPENCL_C_VERSION__ < CL_VERSION_2_0 #ifdef cl_khr_3d_image_writes @@ -15585,7 +15585,7 @@ half4 __purefn __ovld read_imageh(read_only image1d_buffer_t image, int coord); #endif //cl_khr_fp16 // Image read functions for read_write images -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) float4 __purefn __ovld read_imagef(read_write image1d_t image, int coord); int4 __purefn __ovld read_imagei(read_write image1d_t image, int coord); uint4 __purefn __ovld read_imageui(read_write image1d_t image, int coord); @@ -15628,7 +15628,6 @@ float __purefn __ovld read_imagef(read_write image2d_msaa_depth_t image, int2 co float __purefn __ovld read_imagef(read_write image2d_array_msaa_depth_t image, int4 coord, int sample); #endif //cl_khr_gl_msaa_sharing -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) #ifdef cl_khr_mipmap_image float4 __purefn __ovld read_imagef(read_write image1d_t image, sampler_t sampler, float coord, float lod); int4 __purefn __ovld read_imagei(read_write image1d_t image, sampler_t sampler, float coord, float lod); @@ -15679,7 +15678,6 @@ int4 __purefn __ovld read_imagei(read_write image3d_t image, sampler_t sampler, uint4 __purefn __ovld read_imageui(read_write image3d_t image, sampler_t sampler, float4 coord, float4 gradientX, float4 gradientY); #endif //cl_khr_mipmap_image -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) // Image read functions returning half4 type #ifdef cl_khr_fp16 @@ -15690,7 +15688,7 @@ half4 __purefn __ovld read_imageh(read_write image1d_array_t image, int2 coord); half4 __purefn __ovld read_imageh(read_write image2d_array_t image, int4 coord); half4 __purefn __ovld read_imageh(read_write image1d_buffer_t image, int coord); #endif //cl_khr_fp16 -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) /** * Write color value to location specified by coordinate @@ -15834,7 +15832,7 @@ void __ovld write_imageh(write_only image1d_buffer_t image, int coord, half4 col #endif //cl_khr_fp16 // Image write functions for read_write images -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) void __ovld write_imagef(read_write image2d_t image, int2 coord, float4 color); void __ovld write_imagei(read_write image2d_t image, int2 coord, int4 color); void __ovld write_imageui(read_write image2d_t image, int2 coord, uint4 color); @@ -15866,7 +15864,6 @@ void __ovld write_imagef(read_write image2d_depth_t image, int2 coord, float col void __ovld write_imagef(read_write image2d_array_depth_t image, int4 coord, float color); #endif //cl_khr_depth_images -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) #if defined(cl_khr_mipmap_image_writes) void __ovld write_imagef(read_write image1d_t image, int coord, int lod, float4 color); void __ovld write_imagei(read_write image1d_t image, int coord, int lod, int4 color); @@ -15894,7 +15891,6 @@ void __ovld write_imageui(read_write image3d_t image, int4 coord, int lod, uint4 #endif //cl_khr_3d_image_writes #endif //cl_khr_mipmap_image_writes -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) // Image write functions for half4 type #ifdef cl_khr_fp16 @@ -15907,7 +15903,7 @@ void __ovld write_imageh(read_write image1d_array_t image, int2 coord, half4 col void __ovld write_imageh(read_write image2d_array_t image, int4 coord, half4 color); void __ovld write_imageh(read_write image1d_buffer_t image, int coord, half4 color); #endif //cl_khr_fp16 -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) // Note: In OpenCL v1.0/1.1/1.2, image argument of image query builtin functions does not have // access qualifier, which by default assume read_only access qualifier. Image query builtin @@ -15955,7 +15951,7 @@ int __ovld __cnfn get_image_width(write_only image2d_array_msaa_t image); int __ovld __cnfn get_image_width(write_only image2d_array_msaa_depth_t image); #endif //cl_khr_gl_msaa_sharing -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) int __ovld __cnfn get_image_width(read_write image1d_t image); int __ovld __cnfn get_image_width(read_write image1d_buffer_t image); int __ovld __cnfn get_image_width(read_write image2d_t image); @@ -15972,7 +15968,7 @@ int __ovld __cnfn get_image_width(read_write image2d_msaa_depth_t image); int __ovld __cnfn get_image_width(read_write image2d_array_msaa_t image); int __ovld __cnfn get_image_width(read_write image2d_array_msaa_depth_t image); #endif //cl_khr_gl_msaa_sharing -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) /** * Return the image height in pixels. @@ -16007,7 +16003,7 @@ int __ovld __cnfn get_image_height(write_only image2d_array_msaa_t image); int __ovld __cnfn get_image_height(write_only image2d_array_msaa_depth_t image); #endif //cl_khr_gl_msaa_sharing -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) int __ovld __cnfn get_image_height(read_write image2d_t image); int __ovld __cnfn get_image_height(read_write image3d_t image); int __ovld __cnfn get_image_height(read_write image2d_array_t image); @@ -16021,7 +16017,7 @@ int __ovld __cnfn get_image_height(read_write image2d_msaa_depth_t image); int __ovld __cnfn get_image_height(read_write image2d_array_msaa_t image); int __ovld __cnfn get_image_height(read_write image2d_array_msaa_depth_t image); #endif //cl_khr_gl_msaa_sharing -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) /** * Return the image depth in pixels. @@ -16032,9 +16028,9 @@ int __ovld __cnfn get_image_depth(read_only image3d_t image); int __ovld __cnfn get_image_depth(write_only image3d_t image); #endif -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) int __ovld __cnfn get_image_depth(read_write image3d_t image); -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) // OpenCL Extension v2.0 s9.18 - Mipmaps #if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) @@ -16053,9 +16049,11 @@ int __ovld get_image_num_mip_levels(write_only image2d_t image); int __ovld get_image_num_mip_levels(write_only image3d_t image); #endif +#if defined(__opencl_c_read_write_images) int __ovld get_image_num_mip_levels(read_write image1d_t image); int __ovld get_image_num_mip_levels(read_write image2d_t image); int __ovld get_image_num_mip_levels(read_write image3d_t image); +#endif //defined(__opencl_c_read_write_images) int __ovld get_image_num_mip_levels(read_only image1d_array_t image); int __ovld get_image_num_mip_levels(read_only image2d_array_t image); @@ -16067,10 +16065,12 @@ int __ovld get_image_num_mip_levels(write_only image2d_array_t image); int __ovld get_image_num_mip_levels(write_only image2d_array_depth_t image); int __ovld get_image_num_mip_levels(write_only image2d_depth_t image); +#if defined(__opencl_c_read_write_images) int __ovld get_image_num_mip_levels(read_write image1d_array_t image); int __ovld get_image_num_mip_levels(read_write image2d_array_t image); int __ovld get_image_num_mip_levels(read_write image2d_array_depth_t image); int __ovld get_image_num_mip_levels(read_write image2d_depth_t image); +#endif //defined(__opencl_c_read_write_images) #endif //cl_khr_mipmap_image #endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) @@ -16130,7 +16130,7 @@ int __ovld __cnfn get_image_channel_data_type(write_only image2d_array_msaa_t im int __ovld __cnfn get_image_channel_data_type(write_only image2d_array_msaa_depth_t image); #endif //cl_khr_gl_msaa_sharing -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) int __ovld __cnfn get_image_channel_data_type(read_write image1d_t image); int __ovld __cnfn get_image_channel_data_type(read_write image1d_buffer_t image); int __ovld __cnfn get_image_channel_data_type(read_write image2d_t image); @@ -16147,7 +16147,7 @@ int __ovld __cnfn get_image_channel_data_type(read_write image2d_msaa_depth_t im int __ovld __cnfn get_image_channel_data_type(read_write image2d_array_msaa_t image); int __ovld __cnfn get_image_channel_data_type(read_write image2d_array_msaa_depth_t image); #endif //cl_khr_gl_msaa_sharing -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) /** * Return the image channel order. Valid values are: @@ -16202,7 +16202,7 @@ int __ovld __cnfn get_image_channel_order(write_only image2d_array_msaa_t image) int __ovld __cnfn get_image_channel_order(write_only image2d_array_msaa_depth_t image); #endif //cl_khr_gl_msaa_sharing -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) int __ovld __cnfn get_image_channel_order(read_write image1d_t image); int __ovld __cnfn get_image_channel_order(read_write image1d_buffer_t image); int __ovld __cnfn get_image_channel_order(read_write image2d_t image); @@ -16219,7 +16219,7 @@ int __ovld __cnfn get_image_channel_order(read_write image2d_msaa_depth_t image) int __ovld __cnfn get_image_channel_order(read_write image2d_array_msaa_t image); int __ovld __cnfn get_image_channel_order(read_write image2d_array_msaa_depth_t image); #endif //cl_khr_gl_msaa_sharing -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) /** * Return the 2D image width and height as an int2 @@ -16252,7 +16252,7 @@ int2 __ovld __cnfn get_image_dim(write_only image2d_array_msaa_t image); int2 __ovld __cnfn get_image_dim(write_only image2d_array_msaa_depth_t image); #endif //cl_khr_gl_msaa_sharing -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) int2 __ovld __cnfn get_image_dim(read_write image2d_t image); int2 __ovld __cnfn get_image_dim(read_write image2d_array_t image); #ifdef cl_khr_depth_images @@ -16265,7 +16265,7 @@ int2 __ovld __cnfn get_image_dim(read_write image2d_msaa_depth_t image); int2 __ovld __cnfn get_image_dim(read_write image2d_array_msaa_t image); int2 __ovld __cnfn get_image_dim(read_write image2d_array_msaa_depth_t image); #endif //cl_khr_gl_msaa_sharing -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) /** * Return the 3D image width, height, and depth as an @@ -16277,9 +16277,9 @@ int4 __ovld __cnfn get_image_dim(read_only image3d_t image); #ifdef cl_khr_3d_image_writes int4 __ovld __cnfn get_image_dim(write_only image3d_t image); #endif -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) int4 __ovld __cnfn get_image_dim(read_write image3d_t image); -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) /** * Return the image array size. @@ -16305,7 +16305,7 @@ size_t __ovld __cnfn get_image_array_size(write_only image2d_array_msaa_t image_ size_t __ovld __cnfn get_image_array_size(write_only image2d_array_msaa_depth_t image_array); #endif //cl_khr_gl_msaa_sharing -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) size_t __ovld __cnfn get_image_array_size(read_write image1d_array_t image_array); size_t __ovld __cnfn get_image_array_size(read_write image2d_array_t image_array); #ifdef cl_khr_depth_images @@ -16315,7 +16315,7 @@ size_t __ovld __cnfn get_image_array_size(read_write image2d_array_depth_t image size_t __ovld __cnfn get_image_array_size(read_write image2d_array_msaa_t image_array); size_t __ovld __cnfn get_image_array_size(read_write image2d_array_msaa_depth_t image_array); #endif //cl_khr_gl_msaa_sharing -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) /** * Return the number of samples associated with image @@ -16331,12 +16331,12 @@ int __ovld get_image_num_samples(write_only image2d_msaa_depth_t image); int __ovld get_image_num_samples(write_only image2d_array_msaa_t image); int __ovld get_image_num_samples(write_only image2d_array_msaa_depth_t image); -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) int __ovld get_image_num_samples(read_write image2d_msaa_t image); int __ovld get_image_num_samples(read_write image2d_msaa_depth_t image); int __ovld get_image_num_samples(read_write image2d_array_msaa_t image); int __ovld get_image_num_samples(read_write image2d_array_msaa_depth_t image); -#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif //defined(__opencl_c_read_write_images) #endif // OpenCL v2.0 s6.13.15 - Work-group Functions @@ -16450,6 +16450,7 @@ bool __ovld is_valid_reserve_id(reserve_id_t reserve_id); // OpenCL v2.0 s6.13.17 - Enqueue Kernels #if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#ifdef __opencl_c_device_enqueue ndrange_t __ovld ndrange_1D(size_t); ndrange_t __ovld ndrange_1D(size_t, size_t); ndrange_t __ovld ndrange_1D(size_t, size_t, size_t); @@ -16477,6 +16478,7 @@ bool __ovld is_valid_event (clk_event_t event); void __ovld capture_event_profiling_info(clk_event_t, clk_profiling_info, __global void* value); queue_t __ovld get_default_queue(void); +#endif //__opencl_c_device_enqueue #endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) // OpenCL Extension v2.0 s9.17 - Sub-groups @@ -17572,34 +17574,38 @@ uint16 __ovld __conv intel_sub_group_shuffle_xor( uint16 x, uint c ); long __ovld __conv intel_sub_group_shuffle_xor( long x, uint c ); ulong __ovld __conv intel_sub_group_shuffle_xor( ulong x, uint c ); +#if defined(__opencl_c_images) uint __ovld __conv intel_sub_group_block_read( read_only image2d_t image, int2 coord ); uint2 __ovld __conv intel_sub_group_block_read2( read_only image2d_t image, int2 coord ); uint4 __ovld __conv intel_sub_group_block_read4( read_only image2d_t image, int2 coord ); uint8 __ovld __conv intel_sub_group_block_read8( read_only image2d_t image, int2 coord ); +#endif -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) uint __ovld __conv intel_sub_group_block_read(read_write image2d_t image, int2 coord); uint2 __ovld __conv intel_sub_group_block_read2(read_write image2d_t image, int2 coord); uint4 __ovld __conv intel_sub_group_block_read4(read_write image2d_t image, int2 coord); uint8 __ovld __conv intel_sub_group_block_read8(read_write image2d_t image, int2 coord); -#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif // defined(__opencl_c_read_write_images) uint __ovld __conv intel_sub_group_block_read( const __global uint* p ); uint2 __ovld __conv intel_sub_group_block_read2( const __global uint* p ); uint4 __ovld __conv intel_sub_group_block_read4( const __global uint* p ); uint8 __ovld __conv intel_sub_group_block_read8( const __global uint* p ); +#if defined(__opencl_c_images) void __ovld __conv intel_sub_group_block_write(write_only image2d_t image, int2 coord, uint data); void __ovld __conv intel_sub_group_block_write2(write_only image2d_t image, int2 coord, uint2 data); void __ovld __conv intel_sub_group_block_write4(write_only image2d_t image, int2 coord, uint4 data); void __ovld __conv intel_sub_group_block_write8(write_only image2d_t image, int2 coord, uint8 data); +#endif // defined(__opencl_c_images) -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) void __ovld __conv intel_sub_group_block_write(read_write image2d_t image, int2 coord, uint data); void __ovld __conv intel_sub_group_block_write2(read_write image2d_t image, int2 coord, uint2 data); void __ovld __conv intel_sub_group_block_write4(read_write image2d_t image, int2 coord, uint4 data); void __ovld __conv intel_sub_group_block_write8(read_write image2d_t image, int2 coord, uint8 data); -#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif // defined(__opencl_c_read_write_images) void __ovld __conv intel_sub_group_block_write( __global uint* p, uint data ); void __ovld __conv intel_sub_group_block_write2( __global uint* p, uint2 data ); @@ -17712,68 +17718,76 @@ ushort __ovld __conv intel_sub_group_scan_inclusive_min( ushort x ); short __ovld __conv intel_sub_group_scan_inclusive_max( short x ); ushort __ovld __conv intel_sub_group_scan_inclusive_max( ushort x ); +#if defined(__opencl_c_images) uint __ovld __conv intel_sub_group_block_read_ui( read_only image2d_t image, int2 byte_coord ); uint2 __ovld __conv intel_sub_group_block_read_ui2( read_only image2d_t image, int2 byte_coord ); uint4 __ovld __conv intel_sub_group_block_read_ui4( read_only image2d_t image, int2 byte_coord ); uint8 __ovld __conv intel_sub_group_block_read_ui8( read_only image2d_t image, int2 byte_coord ); +#endif // defined(__opencl_c_images) -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) uint __ovld __conv intel_sub_group_block_read_ui( read_write image2d_t image, int2 byte_coord ); uint2 __ovld __conv intel_sub_group_block_read_ui2( read_write image2d_t image, int2 byte_coord ); uint4 __ovld __conv intel_sub_group_block_read_ui4( read_write image2d_t image, int2 byte_coord ); uint8 __ovld __conv intel_sub_group_block_read_ui8( read_write image2d_t image, int2 byte_coord ); -#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif // defined(__opencl_c_read_write_images) uint __ovld __conv intel_sub_group_block_read_ui( const __global uint* p ); uint2 __ovld __conv intel_sub_group_block_read_ui2( const __global uint* p ); uint4 __ovld __conv intel_sub_group_block_read_ui4( const __global uint* p ); uint8 __ovld __conv intel_sub_group_block_read_ui8( const __global uint* p ); +#if defined(__opencl_c_images) void __ovld __conv intel_sub_group_block_write_ui( read_only image2d_t image, int2 byte_coord, uint data ); void __ovld __conv intel_sub_group_block_write_ui2( read_only image2d_t image, int2 byte_coord, uint2 data ); void __ovld __conv intel_sub_group_block_write_ui4( read_only image2d_t image, int2 byte_coord, uint4 data ); void __ovld __conv intel_sub_group_block_write_ui8( read_only image2d_t image, int2 byte_coord, uint8 data ); +#endif //defined(__opencl_c_images) -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) void __ovld __conv intel_sub_group_block_write_ui( read_write image2d_t image, int2 byte_coord, uint data ); void __ovld __conv intel_sub_group_block_write_ui2( read_write image2d_t image, int2 byte_coord, uint2 data ); void __ovld __conv intel_sub_group_block_write_ui4( read_write image2d_t image, int2 byte_coord, uint4 data ); void __ovld __conv intel_sub_group_block_write_ui8( read_write image2d_t image, int2 byte_coord, uint8 data ); -#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif // defined(__opencl_c_read_write_images) void __ovld __conv intel_sub_group_block_write_ui( __global uint* p, uint data ); void __ovld __conv intel_sub_group_block_write_ui2( __global uint* p, uint2 data ); void __ovld __conv intel_sub_group_block_write_ui4( __global uint* p, uint4 data ); void __ovld __conv intel_sub_group_block_write_ui8( __global uint* p, uint8 data ); +#if defined(__opencl_c_images) ushort __ovld __conv intel_sub_group_block_read_us( read_only image2d_t image, int2 coord ); ushort2 __ovld __conv intel_sub_group_block_read_us2( read_only image2d_t image, int2 coord ); ushort4 __ovld __conv intel_sub_group_block_read_us4( read_only image2d_t image, int2 coord ); ushort8 __ovld __conv intel_sub_group_block_read_us8( read_only image2d_t image, int2 coord ); +#endif // defined(__opencl_c_images) -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) ushort __ovld __conv intel_sub_group_block_read_us(read_write image2d_t image, int2 coord); ushort2 __ovld __conv intel_sub_group_block_read_us2(read_write image2d_t image, int2 coord); ushort4 __ovld __conv intel_sub_group_block_read_us4(read_write image2d_t image, int2 coord); ushort8 __ovld __conv intel_sub_group_block_read_us8(read_write image2d_t image, int2 coord); -#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif // defined(__opencl_c_read_write_images) ushort __ovld __conv intel_sub_group_block_read_us( const __global ushort* p ); ushort2 __ovld __conv intel_sub_group_block_read_us2( const __global ushort* p ); ushort4 __ovld __conv intel_sub_group_block_read_us4( const __global ushort* p ); ushort8 __ovld __conv intel_sub_group_block_read_us8( const __global ushort* p ); +#if defined(__opencl_c_images) void __ovld __conv intel_sub_group_block_write_us(write_only image2d_t image, int2 coord, ushort data); void __ovld __conv intel_sub_group_block_write_us2(write_only image2d_t image, int2 coord, ushort2 data); void __ovld __conv intel_sub_group_block_write_us4(write_only image2d_t image, int2 coord, ushort4 data); void __ovld __conv intel_sub_group_block_write_us8(write_only image2d_t image, int2 coord, ushort8 data); +#endif // defined(__opencl_c_images) -#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#if defined(__opencl_c_read_write_images) void __ovld __conv intel_sub_group_block_write_us(read_write image2d_t image, int2 coord, ushort data); void __ovld __conv intel_sub_group_block_write_us2(read_write image2d_t image, int2 coord, ushort2 data); void __ovld __conv intel_sub_group_block_write_us4(read_write image2d_t image, int2 coord, ushort4 data); void __ovld __conv intel_sub_group_block_write_us8(read_write image2d_t image, int2 coord, ushort8 data); -#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +#endif // defined(__opencl_c_read_write_images) void __ovld __conv intel_sub_group_block_write_us( __global ushort* p, ushort data ); void __ovld __conv intel_sub_group_block_write_us2( __global ushort* p, ushort2 data ); @@ -17891,6 +17905,7 @@ short2 __ovld intel_sub_group_avc_ime_adjust_ref_offset( short2 ref_offset, ushort2 src_coord, ushort2 ref_window_size, ushort2 image_size); +#if defined(__opencl_c_images) intel_sub_group_avc_ime_result_t __ovld intel_sub_group_avc_ime_evaluate_with_single_reference( read_only image2d_t src_image, read_only image2d_t ref_image, @@ -17931,6 +17946,7 @@ intel_sub_group_avc_ime_evaluate_with_dual_reference_streaminout( read_only image2d_t bwd_ref_image, sampler_t vme_media_sampler, intel_sub_group_avc_ime_payload_t payload, intel_sub_group_avc_ime_dual_reference_streamin_t streamin_components); +#endif intel_sub_group_avc_ime_single_reference_streamin_t __ovld intel_sub_group_avc_ime_get_single_reference_streamin( @@ -17995,6 +18011,7 @@ intel_sub_group_avc_ref_payload_t __ovld intel_sub_group_avc_ref_set_bilinear_filter_enable( intel_sub_group_avc_ref_payload_t payload); +#if defined(__opencl_c_images) intel_sub_group_avc_ref_result_t __ovld intel_sub_group_avc_ref_evaluate_with_single_reference( read_only image2d_t src_image, read_only image2d_t ref_image, @@ -18013,6 +18030,7 @@ intel_sub_group_avc_ref_evaluate_with_multi_reference( read_only image2d_t src_image, uint packed_reference_ids, uchar packed_reference_field_polarities, sampler_t vme_media_sampler, intel_sub_group_avc_ref_payload_t payload); +#endif //defined(__opencl_c_images) // SIC built-in functions intel_sub_group_avc_sic_payload_t __ovld @@ -18063,6 +18081,7 @@ intel_sub_group_avc_sic_set_block_based_raw_skip_sad( uchar block_based_skip_type, intel_sub_group_avc_sic_payload_t payload); +#if defined(__opencl_c_images) intel_sub_group_avc_sic_result_t __ovld intel_sub_group_avc_sic_evaluate_ipe( read_only image2d_t src_image, sampler_t vme_media_sampler, @@ -18085,6 +18104,7 @@ intel_sub_group_avc_sic_evaluate_with_multi_reference( read_only image2d_t src_image, uint packed_reference_ids, uchar packed_reference_field_polarities, sampler_t vme_media_sampler, intel_sub_group_avc_sic_payload_t payload); +#endif //defined(__opencl_c_images) uchar __ovld intel_sub_group_avc_sic_get_ipe_luma_shape( intel_sub_group_avc_sic_result_t result); diff --git contrib/llvm-project/clang/lib/Headers/smmintrin.h contrib/llvm-project/clang/lib/Headers/smmintrin.h index 710e55aaa120..0df59c5fcc59 100644 --- contrib/llvm-project/clang/lib/Headers/smmintrin.h +++ contrib/llvm-project/clang/lib/Headers/smmintrin.h @@ -668,7 +668,7 @@ _mm_stream_load_si128 (__m128i const *__V) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_min_epi8 (__m128i __V1, __m128i __V2) { - return (__m128i) __builtin_ia32_pminsb128 ((__v16qi) __V1, (__v16qi) __V2); + return (__m128i) __builtin_elementwise_min((__v16qs) __V1, (__v16qs) __V2); } /// Compares the corresponding elements of two 128-bit vectors of @@ -687,7 +687,7 @@ _mm_min_epi8 (__m128i __V1, __m128i __V2) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_max_epi8 (__m128i __V1, __m128i __V2) { - return (__m128i) __builtin_ia32_pmaxsb128 ((__v16qi) __V1, (__v16qi) __V2); + return (__m128i) __builtin_elementwise_max((__v16qs) __V1, (__v16qs) __V2); } /// Compares the corresponding elements of two 128-bit vectors of @@ -706,7 +706,7 @@ _mm_max_epi8 (__m128i __V1, __m128i __V2) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_min_epu16 (__m128i __V1, __m128i __V2) { - return (__m128i) __builtin_ia32_pminuw128 ((__v8hi) __V1, (__v8hi) __V2); + return (__m128i) __builtin_elementwise_min((__v8hu) __V1, (__v8hu) __V2); } /// Compares the corresponding elements of two 128-bit vectors of @@ -725,7 +725,7 @@ _mm_min_epu16 (__m128i __V1, __m128i __V2) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_max_epu16 (__m128i __V1, __m128i __V2) { - return (__m128i) __builtin_ia32_pmaxuw128 ((__v8hi) __V1, (__v8hi) __V2); + return (__m128i) __builtin_elementwise_max((__v8hu) __V1, (__v8hu) __V2); } /// Compares the corresponding elements of two 128-bit vectors of @@ -744,7 +744,7 @@ _mm_max_epu16 (__m128i __V1, __m128i __V2) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_min_epi32 (__m128i __V1, __m128i __V2) { - return (__m128i) __builtin_ia32_pminsd128 ((__v4si) __V1, (__v4si) __V2); + return (__m128i) __builtin_elementwise_min((__v4si) __V1, (__v4si) __V2); } /// Compares the corresponding elements of two 128-bit vectors of @@ -763,7 +763,7 @@ _mm_min_epi32 (__m128i __V1, __m128i __V2) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_max_epi32 (__m128i __V1, __m128i __V2) { - return (__m128i) __builtin_ia32_pmaxsd128 ((__v4si) __V1, (__v4si) __V2); + return (__m128i) __builtin_elementwise_max((__v4si) __V1, (__v4si) __V2); } /// Compares the corresponding elements of two 128-bit vectors of @@ -782,7 +782,7 @@ _mm_max_epi32 (__m128i __V1, __m128i __V2) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_min_epu32 (__m128i __V1, __m128i __V2) { - return (__m128i) __builtin_ia32_pminud128((__v4si) __V1, (__v4si) __V2); + return (__m128i) __builtin_elementwise_min((__v4su) __V1, (__v4su) __V2); } /// Compares the corresponding elements of two 128-bit vectors of @@ -801,7 +801,7 @@ _mm_min_epu32 (__m128i __V1, __m128i __V2) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_max_epu32 (__m128i __V1, __m128i __V2) { - return (__m128i) __builtin_ia32_pmaxud128((__v4si) __V1, (__v4si) __V2); + return (__m128i) __builtin_elementwise_max((__v4su) __V1, (__v4su) __V2); } /* SSE4 Insertion and Extraction from XMM Register Instructions. */ diff --git contrib/llvm-project/clang/lib/Headers/stdatomic.h contrib/llvm-project/clang/lib/Headers/stdatomic.h index 1e47bcb2bacf..780bcc2dfea1 100644 --- contrib/llvm-project/clang/lib/Headers/stdatomic.h +++ contrib/llvm-project/clang/lib/Headers/stdatomic.h @@ -44,6 +44,11 @@ extern "C" { /* 7.17.2 Initialization */ #define ATOMIC_VAR_INIT(value) (value) +#if (__STDC_VERSION__ >= 201710L || __cplusplus >= 202002L) && \ + !defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS) +/* ATOMIC_VAR_INIT was deprecated in C17 and C++20. */ +#pragma clang deprecated(ATOMIC_VAR_INIT) +#endif #define atomic_init __c11_atomic_init /* 7.17.3 Order and consistency */ @@ -153,6 +158,10 @@ typedef _Atomic(uintmax_t) atomic_uintmax_t; typedef struct atomic_flag { atomic_bool _Value; } atomic_flag; #define ATOMIC_FLAG_INIT { 0 } +#if __cplusplus >= 202002L && !defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS) +/* ATOMIC_FLAG_INIT was deprecated in C++20 but is not deprecated in C. */ +#pragma clang deprecated(ATOMIC_FLAG_INIT) +#endif /* These should be provided by the libc implementation. */ #ifdef __cplusplus diff --git contrib/llvm-project/clang/lib/Headers/stdint.h contrib/llvm-project/clang/lib/Headers/stdint.h index 192f653e95a1..4790c25a2774 100644 --- contrib/llvm-project/clang/lib/Headers/stdint.h +++ contrib/llvm-project/clang/lib/Headers/stdint.h @@ -461,6 +461,18 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT64_MAX INT64_C( 9223372036854775807) # define INT64_MIN (-INT64_C( 9223372036854775807)-1) # define UINT64_MAX UINT64_C(18446744073709551615) +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT64_WIDTH 64 +# define INT64_WIDTH UINT64_WIDTH + +# define __UINT_LEAST64_WIDTH UINT64_WIDTH +# define __UINT_LEAST32_WIDTH UINT64_WIDTH +# define __UINT_LEAST16_WIDTH UINT64_WIDTH +# define __UINT_LEAST8_MAX UINT64_MAX +#endif /* __STDC_VERSION__ */ + # define __INT_LEAST64_MIN INT64_MIN # define __INT_LEAST64_MAX INT64_MAX # define __UINT_LEAST64_MAX UINT64_MAX @@ -482,6 +494,15 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT_FAST64_MIN __INT_LEAST64_MIN # define INT_FAST64_MAX __INT_LEAST64_MAX # define UINT_FAST64_MAX __UINT_LEAST64_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT_LEAST64_WIDTH __UINT_LEAST64_WIDTH +# define INT_LEAST64_WIDTH UINT_LEAST64_WIDTH +# define UINT_FAST64_WIDTH __UINT_LEAST64_WIDTH +# define INT_FAST64_WIDTH UINT_FAST64_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT_LEAST64_MIN */ @@ -495,6 +516,7 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT_FAST56_MIN INT56_MIN # define INT_FAST56_MAX INT56_MAX # define UINT_FAST56_MAX UINT56_MAX + # define __INT_LEAST32_MIN INT56_MIN # define __INT_LEAST32_MAX INT56_MAX # define __UINT_LEAST32_MAX UINT56_MAX @@ -504,6 +526,20 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define __INT_LEAST8_MIN INT56_MIN # define __INT_LEAST8_MAX INT56_MAX # define __UINT_LEAST8_MAX UINT56_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT56_WIDTH 56 +# define INT56_WIDTH UINT56_WIDTH +# define UINT_LEAST56_WIDTH UINT56_WIDTH +# define INT_LEAST56_WIDTH UINT_LEAST56_WIDTH +# define UINT_FAST56_WIDTH UINT56_WIDTH +# define INT_FAST56_WIDTH UINT_FAST56_WIDTH +# define __UINT_LEAST32_WIDTH UINT56_WIDTH +# define __UINT_LEAST16_WIDTH UINT56_WIDTH +# define __UINT_LEAST8_WIDTH UINT56_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT56_TYPE__ */ @@ -517,6 +553,7 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT_FAST48_MIN INT48_MIN # define INT_FAST48_MAX INT48_MAX # define UINT_FAST48_MAX UINT48_MAX + # define __INT_LEAST32_MIN INT48_MIN # define __INT_LEAST32_MAX INT48_MAX # define __UINT_LEAST32_MAX UINT48_MAX @@ -526,6 +563,20 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define __INT_LEAST8_MIN INT48_MIN # define __INT_LEAST8_MAX INT48_MAX # define __UINT_LEAST8_MAX UINT48_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +#define UINT48_WIDTH 48 +#define INT48_WIDTH UINT48_WIDTH +#define UINT_LEAST48_WIDTH UINT48_WIDTH +#define INT_LEAST48_WIDTH UINT_LEAST48_WIDTH +#define UINT_FAST48_WIDTH UINT48_WIDTH +#define INT_FAST48_WIDTH UINT_FAST48_WIDTH +#define __UINT_LEAST32_WIDTH UINT48_WIDTH +#define __UINT_LEAST16_WIDTH UINT48_WIDTH +#define __UINT_LEAST8_WIDTH UINT48_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT48_TYPE__ */ @@ -539,6 +590,7 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT_FAST40_MIN INT40_MIN # define INT_FAST40_MAX INT40_MAX # define UINT_FAST40_MAX UINT40_MAX + # define __INT_LEAST32_MIN INT40_MIN # define __INT_LEAST32_MAX INT40_MAX # define __UINT_LEAST32_MAX UINT40_MAX @@ -548,6 +600,20 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define __INT_LEAST8_MIN INT40_MIN # define __INT_LEAST8_MAX INT40_MAX # define __UINT_LEAST8_MAX UINT40_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT40_WIDTH 40 +# define INT40_WIDTH UINT40_WIDTH +# define UINT_LEAST40_WIDTH UINT40_WIDTH +# define INT_LEAST40_WIDTH UINT_LEAST40_WIDTH +# define UINT_FAST40_WIDTH UINT40_WIDTH +# define INT_FAST40_WIDTH UINT_FAST40_WIDTH +# define __UINT_LEAST32_WIDTH UINT40_WIDTH +# define __UINT_LEAST16_WIDTH UINT40_WIDTH +# define __UINT_LEAST8_WIDTH UINT40_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT40_TYPE__ */ @@ -555,6 +621,7 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT32_MAX INT32_C(2147483647) # define INT32_MIN (-INT32_C(2147483647)-1) # define UINT32_MAX UINT32_C(4294967295) + # define __INT_LEAST32_MIN INT32_MIN # define __INT_LEAST32_MAX INT32_MAX # define __UINT_LEAST32_MAX UINT32_MAX @@ -564,6 +631,16 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define __INT_LEAST8_MIN INT32_MIN # define __INT_LEAST8_MAX INT32_MAX # define __UINT_LEAST8_MAX UINT32_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT32_WIDTH 32 +# define INT32_WIDTH UINT32_WIDTH +# define __UINT_LEAST32_WIDTH UINT32_WIDTH +# define __UINT_LEAST16_WIDTH UINT32_WIDTH +# define __UINT_LEAST8_WIDTH UINT32_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT32_TYPE__ */ #ifdef __INT_LEAST32_MIN @@ -573,6 +650,15 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT_FAST32_MIN __INT_LEAST32_MIN # define INT_FAST32_MAX __INT_LEAST32_MAX # define UINT_FAST32_MAX __UINT_LEAST32_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT_LEAST32_WIDTH __UINT_LEAST32_WIDTH +# define INT_LEAST32_WIDTH UINT_LEAST32_WIDTH +# define UINT_FAST32_WIDTH __UINT_LEAST32_WIDTH +# define INT_FAST32_WIDTH UINT_FAST32_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT_LEAST32_MIN */ @@ -586,12 +672,26 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT_FAST24_MIN INT24_MIN # define INT_FAST24_MAX INT24_MAX # define UINT_FAST24_MAX UINT24_MAX + # define __INT_LEAST16_MIN INT24_MIN # define __INT_LEAST16_MAX INT24_MAX # define __UINT_LEAST16_MAX UINT24_MAX # define __INT_LEAST8_MIN INT24_MIN # define __INT_LEAST8_MAX INT24_MAX # define __UINT_LEAST8_MAX UINT24_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT24_WIDTH 24 +# define INT24_WIDTH UINT24_WIDTH +# define UINT_LEAST24_WIDTH UINT24_WIDTH +# define INT_LEAST24_WIDTH UINT_LEAST24_WIDTH +# define UINT_FAST24_WIDTH UINT24_WIDTH +# define INT_FAST24_WIDTH UINT_FAST24_WIDTH +# define __UINT_LEAST16_WIDTH UINT24_WIDTH +# define __UINT_LEAST8_WIDTH UINT24_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT24_TYPE__ */ @@ -599,12 +699,22 @@ typedef __UINTMAX_TYPE__ uintmax_t; #define INT16_MAX INT16_C(32767) #define INT16_MIN (-INT16_C(32767)-1) #define UINT16_MAX UINT16_C(65535) + # define __INT_LEAST16_MIN INT16_MIN # define __INT_LEAST16_MAX INT16_MAX # define __UINT_LEAST16_MAX UINT16_MAX # define __INT_LEAST8_MIN INT16_MIN # define __INT_LEAST8_MAX INT16_MAX # define __UINT_LEAST8_MAX UINT16_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT16_WIDTH 16 +# define INT16_WIDTH UINT16_WIDTH +# define __UINT_LEAST16_WIDTH UINT16_WIDTH +# define __UINT_LEAST8_WIDTH UINT16_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT16_TYPE__ */ #ifdef __INT_LEAST16_MIN @@ -614,6 +724,15 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT_FAST16_MIN __INT_LEAST16_MIN # define INT_FAST16_MAX __INT_LEAST16_MAX # define UINT_FAST16_MAX __UINT_LEAST16_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT_LEAST16_WIDTH __UINT_LEAST16_WIDTH +# define INT_LEAST16_WIDTH UINT_LEAST16_WIDTH +# define UINT_FAST16_WIDTH __UINT_LEAST16_WIDTH +# define INT_FAST16_WIDTH UINT_FAST16_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT_LEAST16_MIN */ @@ -621,9 +740,18 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT8_MAX INT8_C(127) # define INT8_MIN (-INT8_C(127)-1) # define UINT8_MAX UINT8_C(255) + # define __INT_LEAST8_MIN INT8_MIN # define __INT_LEAST8_MAX INT8_MAX # define __UINT_LEAST8_MAX UINT8_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT8_WIDTH 8 +# define INT8_WIDTH UINT8_WIDTH +# define __UINT_LEAST8_WIDTH UINT8_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT8_TYPE__ */ #ifdef __INT_LEAST8_MIN @@ -633,6 +761,15 @@ typedef __UINTMAX_TYPE__ uintmax_t; # define INT_FAST8_MIN __INT_LEAST8_MIN # define INT_FAST8_MAX __INT_LEAST8_MAX # define UINT_FAST8_MAX __UINT_LEAST8_MAX + +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +# define UINT_LEAST8_WIDTH __UINT_LEAST8_WIDTH +# define INT_LEAST8_WIDTH UINT_LEAST8_WIDTH +# define UINT_FAST8_WIDTH __UINT_LEAST8_WIDTH +# define INT_FAST8_WIDTH UINT_FAST8_WIDTH +#endif /* __STDC_VERSION__ */ #endif /* __INT_LEAST8_MIN */ /* Some utility macros */ @@ -652,6 +789,16 @@ typedef __UINTMAX_TYPE__ uintmax_t; #define PTRDIFF_MAX __PTRDIFF_MAX__ #define SIZE_MAX __SIZE_MAX__ +/* C2x 7.20.2.4 Width of integer types capable of holding object pointers. */ +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +/* NB: The C standard requires that these be the same value, but the compiler + exposes separate internal width macros. */ +#define INTPTR_WIDTH __INTPTR_WIDTH__ +#define UINTPTR_WIDTH __UINTPTR_WIDTH__ +#endif + /* ISO9899:2011 7.20 (C11 Annex K): Define RSIZE_MAX if __STDC_WANT_LIB_EXT1__ * is enabled. */ #if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 @@ -663,6 +810,16 @@ typedef __UINTMAX_TYPE__ uintmax_t; #define INTMAX_MAX __INTMAX_MAX__ #define UINTMAX_MAX __UINTMAX_MAX__ +/* C2x 7.20.2.5 Width of greatest-width integer types. */ +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +/* NB: The C standard requires that these be the same value, but the compiler + exposes separate internal width macros. */ +#define INTMAX_WIDTH __INTMAX_WIDTH__ +#define UINTMAX_WIDTH __UINTMAX_WIDTH__ +#endif + /* C99 7.18.3 Limits of other integer types. */ #define SIG_ATOMIC_MIN __INTN_MIN(__SIG_ATOMIC_WIDTH__) #define SIG_ATOMIC_MAX __INTN_MAX(__SIG_ATOMIC_WIDTH__) @@ -689,5 +846,16 @@ typedef __UINTMAX_TYPE__ uintmax_t; #define INTMAX_C(v) __int_c(v, __INTMAX_C_SUFFIX__) #define UINTMAX_C(v) __int_c(v, __UINTMAX_C_SUFFIX__) +/* C2x 7.20.3.x Width of other integer types. */ +/* FIXME: This is using the placeholder dates Clang produces for these macros + in C2x mode; switch to the correct values once they've been published. */ +#if __STDC_VERSION__ >= 202000L +#define PTRDIFF_WIDTH __PTRDIFF_WIDTH__ +#define SIG_ATOMIC_WIDTH __SIG_ATOMIC_WIDTH__ +#define SIZE_WIDTH __SIZE_WIDTH__ +#define WCHAR_WIDTH __WCHAR_WIDTH__ +#define WINT_WIDTH __WINT_WIDTH__ +#endif + #endif /* __STDC_HOSTED__ */ #endif /* __CLANG_STDINT_H */ diff --git contrib/llvm-project/clang/lib/Headers/tmmintrin.h contrib/llvm-project/clang/lib/Headers/tmmintrin.h index bcffa8187801..cb9be2349de5 100644 --- contrib/llvm-project/clang/lib/Headers/tmmintrin.h +++ contrib/llvm-project/clang/lib/Headers/tmmintrin.h @@ -53,7 +53,7 @@ _mm_abs_pi8(__m64 __a) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_abs_epi8(__m128i __a) { - return (__m128i)__builtin_ia32_pabsb128((__v16qi)__a); + return (__m128i)__builtin_elementwise_abs((__v16qs)__a); } /// Computes the absolute value of each of the packed 16-bit signed @@ -89,7 +89,7 @@ _mm_abs_pi16(__m64 __a) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_abs_epi16(__m128i __a) { - return (__m128i)__builtin_ia32_pabsw128((__v8hi)__a); + return (__m128i)__builtin_elementwise_abs((__v8hi)__a); } /// Computes the absolute value of each of the packed 32-bit signed @@ -125,7 +125,7 @@ _mm_abs_pi32(__m64 __a) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_abs_epi32(__m128i __a) { - return (__m128i)__builtin_ia32_pabsd128((__v4si)__a); + return (__m128i)__builtin_elementwise_abs((__v4si)__a); } /// Concatenates the two 128-bit integer vector operands, and diff --git contrib/llvm-project/clang/lib/Headers/vaesintrin.h contrib/llvm-project/clang/lib/Headers/vaesintrin.h index f3c0807bb94a..294dcff2addd 100644 --- contrib/llvm-project/clang/lib/Headers/vaesintrin.h +++ contrib/llvm-project/clang/lib/Headers/vaesintrin.h @@ -82,4 +82,4 @@ static __inline__ __m512i __DEFAULT_FN_ATTRS_F #undef __DEFAULT_FN_ATTRS #undef __DEFAULT_FN_ATTRS_F -#endif +#endif // __VAESINTRIN_H diff --git contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.cpp contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.cpp index 84eabc3a210f..4ade8b8bb074 100644 --- contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.cpp +++ contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.cpp @@ -256,7 +256,7 @@ IncrementalParser::Parse(llvm::StringRef input) { /*LoadedOffset=*/0, NewLoc); // NewLoc only used for diags. - if (PP.EnterSourceFile(FID, /*DirLookup=*/0, NewLoc)) + if (PP.EnterSourceFile(FID, /*DirLookup=*/nullptr, NewLoc)) return llvm::make_error<llvm::StringError>("Parsing failed. " "Cannot enter source file.", std::error_code()); diff --git contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.h contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.h index e5ce798025d9..d1f454f21239 100644 --- contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.h +++ contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.h @@ -30,9 +30,6 @@ class LLVMContext; namespace clang { class ASTConsumer; class CompilerInstance; -class CodeGenerator; -class DeclGroupRef; -class FrontendAction; class IncrementalAction; class Parser; diff --git contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp index a0b60118a1a8..39c125c395ef 100644 --- contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp +++ contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp @@ -29,6 +29,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Capacity.h" #include "llvm/Support/Errc.h" @@ -89,16 +90,10 @@ HeaderSearch::HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts, void HeaderSearch::PrintStats() { llvm::errs() << "\n*** HeaderSearch Stats:\n" << FileInfo.size() << " files tracked.\n"; - unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0; - for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) { + unsigned NumOnceOnlyFiles = 0; + for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) NumOnceOnlyFiles += (FileInfo[i].isPragmaOnce || FileInfo[i].isImport); - if (MaxNumIncludes < FileInfo[i].NumIncludes) - MaxNumIncludes = FileInfo[i].NumIncludes; - NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1; - } - llvm::errs() << " " << NumOnceOnlyFiles << " #import/#pragma once files.\n" - << " " << NumSingleIncludedFiles << " included exactly once.\n" - << " " << MaxNumIncludes << " max times a file is included.\n"; + llvm::errs() << " " << NumOnceOnlyFiles << " #import/#pragma once files.\n"; llvm::errs() << " " << NumIncluded << " #include/#include_next/#import.\n" << " " << NumMultiIncludeFileOptzn @@ -108,6 +103,30 @@ void HeaderSearch::PrintStats() { << NumSubFrameworkLookups << " subframework lookups.\n"; } +void HeaderSearch::SetSearchPaths( + std::vector<DirectoryLookup> dirs, unsigned int angledDirIdx, + unsigned int systemDirIdx, bool noCurDirSearch, + llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) { + assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() && + "Directory indices are unordered"); + SearchDirs = std::move(dirs); + SearchDirsUsage.assign(SearchDirs.size(), false); + AngledDirIdx = angledDirIdx; + SystemDirIdx = systemDirIdx; + NoCurDirSearch = noCurDirSearch; + SearchDirToHSEntry = std::move(searchDirToHSEntry); + //LookupFileCache.clear(); +} + +void HeaderSearch::AddSearchPath(const DirectoryLookup &dir, bool isAngled) { + unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx; + SearchDirs.insert(SearchDirs.begin() + idx, dir); + SearchDirsUsage.insert(SearchDirsUsage.begin() + idx, false); + if (!isAngled) + AngledDirIdx++; + SystemDirIdx++; +} + std::vector<bool> HeaderSearch::computeUserEntryUsage() const { std::vector<bool> UserEntryUsage(HSOpts->UserEntries.size()); for (unsigned I = 0, E = SearchDirsUsage.size(); I < E; ++I) { @@ -720,7 +739,8 @@ static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) { } static bool isFrameworkStylePath(StringRef Path, bool &IsPrivateHeader, - SmallVectorImpl<char> &FrameworkName) { + SmallVectorImpl<char> &FrameworkName, + SmallVectorImpl<char> &IncludeSpelling) { using namespace llvm::sys; path::const_iterator I = path::begin(Path); path::const_iterator E = path::end(Path); @@ -736,15 +756,22 @@ static bool isFrameworkStylePath(StringRef Path, bool &IsPrivateHeader, // and some other variations among these lines. int FoundComp = 0; while (I != E) { - if (*I == "Headers") + if (*I == "Headers") { ++FoundComp; - if (I->endswith(".framework")) { - FrameworkName.append(I->begin(), I->end()); - ++FoundComp; - } - if (*I == "PrivateHeaders") { + } else if (*I == "PrivateHeaders") { ++FoundComp; IsPrivateHeader = true; + } else if (I->endswith(".framework")) { + StringRef Name = I->drop_back(10); // Drop .framework + // Need to reset the strings and counter to support nested frameworks. + FrameworkName.clear(); + FrameworkName.append(Name.begin(), Name.end()); + IncludeSpelling.clear(); + IncludeSpelling.append(Name.begin(), Name.end()); + FoundComp = 1; + } else if (FoundComp >= 2) { + IncludeSpelling.push_back('/'); + IncludeSpelling.append(I->begin(), I->end()); } ++I; } @@ -759,20 +786,24 @@ diagnoseFrameworkInclude(DiagnosticsEngine &Diags, SourceLocation IncludeLoc, bool FoundByHeaderMap = false) { bool IsIncluderPrivateHeader = false; SmallString<128> FromFramework, ToFramework; - if (!isFrameworkStylePath(Includer, IsIncluderPrivateHeader, FromFramework)) + SmallString<128> FromIncludeSpelling, ToIncludeSpelling; + if (!isFrameworkStylePath(Includer, IsIncluderPrivateHeader, FromFramework, + FromIncludeSpelling)) return; bool IsIncludeePrivateHeader = false; - bool IsIncludeeInFramework = isFrameworkStylePath( - IncludeFE->getName(), IsIncludeePrivateHeader, ToFramework); + bool IsIncludeeInFramework = + isFrameworkStylePath(IncludeFE->getName(), IsIncludeePrivateHeader, + ToFramework, ToIncludeSpelling); if (!isAngled && !FoundByHeaderMap) { SmallString<128> NewInclude("<"); if (IsIncludeeInFramework) { - NewInclude += ToFramework.str().drop_back(10); // drop .framework - NewInclude += "/"; + NewInclude += ToIncludeSpelling; + NewInclude += ">"; + } else { + NewInclude += IncludeFilename; + NewInclude += ">"; } - NewInclude += IncludeFilename; - NewInclude += ">"; Diags.Report(IncludeLoc, diag::warn_quoted_include_in_framework_header) << IncludeFilename << FixItHint::CreateReplacement(IncludeLoc, NewInclude); @@ -794,12 +825,15 @@ diagnoseFrameworkInclude(DiagnosticsEngine &Diags, SourceLocation IncludeLoc, /// search is needed. Microsoft mode will pass all \#including files. Optional<FileEntryRef> HeaderSearch::LookupFile( StringRef Filename, SourceLocation IncludeLoc, bool isAngled, - const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, + const DirectoryLookup *FromDir, const DirectoryLookup **CurDirArg, ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache, bool BuildSystemModule) { + const DirectoryLookup *CurDirLocal = nullptr; + const DirectoryLookup *&CurDir = CurDirArg ? *CurDirArg : CurDirLocal; + if (IsMapped) *IsMapped = false; @@ -1046,7 +1080,7 @@ Optional<FileEntryRef> HeaderSearch::LookupFile( ScratchFilename += Filename; Optional<FileEntryRef> File = LookupFile( - ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir, + ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, &CurDir, Includers.front(), SearchPath, RelativePath, RequestingModule, SuggestedModule, IsMapped, /*IsFrameworkFound=*/nullptr); @@ -1203,7 +1237,6 @@ static void mergeHeaderFileInfo(HeaderFileInfo &HFI, HFI.isImport |= OtherHFI.isImport; HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; HFI.isModuleHeader |= OtherHFI.isModuleHeader; - HFI.NumIncludes += OtherHFI.NumIncludes; if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { HFI.ControllingMacro = OtherHFI.ControllingMacro; @@ -1364,7 +1397,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP, FileInfo.isImport = true; // Has this already been #import'ed or #include'd? - if (FileInfo.NumIncludes && !TryEnterImported()) + if (PP.alreadyIncluded(File) && !TryEnterImported()) return false; } else { // Otherwise, if this is a #include of a file that was previously #import'd @@ -1387,10 +1420,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP, } } - // Increment the number of times this file has been included. - ++FileInfo.NumIncludes; - - IsFirstIncludeOfFile = FileInfo.NumIncludes == 1; + IsFirstIncludeOfFile = PP.markIncluded(File); return true; } @@ -1779,11 +1809,8 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { } // Populate the list of modules. - for (ModuleMap::module_iterator M = ModMap.module_begin(), - MEnd = ModMap.module_end(); - M != MEnd; ++M) { - Modules.push_back(M->getValue()); - } + llvm::transform(ModMap.modules(), std::back_inserter(Modules), + [](const auto &NameAndMod) { return NameAndMod.second; }); } void HeaderSearch::loadTopLevelSystemModules() { @@ -1843,9 +1870,9 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics( using namespace llvm::sys; unsigned BestPrefixLength = 0; - // Checks whether Dir and File shares a common prefix, if they do and that's - // the longest prefix we've seen so for it returns true and updates the - // BestPrefixLength accordingly. + // Checks whether `Dir` is a strict path prefix of `File`. If so and that's + // the longest prefix we've seen so for it, returns true and updates the + // `BestPrefixLength` accordingly. auto CheckDir = [&](llvm::StringRef Dir) -> bool { llvm::SmallString<32> DirPath(Dir.begin(), Dir.end()); if (!WorkingDir.empty() && !path::is_absolute(Dir)) @@ -1880,26 +1907,48 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics( path::is_separator(NI->front()) && path::is_separator(DI->front())) continue; + // Special case Apple .sdk folders since the search path is typically a + // symlink like `iPhoneSimulator14.5.sdk` while the file is instead + // located in `iPhoneSimulator.sdk` (the real folder). + if (NI->endswith(".sdk") && DI->endswith(".sdk")) { + StringRef NBasename = path::stem(*NI); + StringRef DBasename = path::stem(*DI); + if (DBasename.startswith(NBasename)) + continue; + } + if (*NI != *DI) break; } return false; }; + bool BestPrefixIsFramework = false; for (unsigned I = 0; I != SearchDirs.size(); ++I) { - // FIXME: Support this search within frameworks. - if (!SearchDirs[I].isNormalDir()) - continue; - - StringRef Dir = SearchDirs[I].getDir()->getName(); - if (CheckDir(Dir) && IsSystem) - *IsSystem = BestPrefixLength ? I >= SystemDirIdx : false; + if (SearchDirs[I].isNormalDir()) { + StringRef Dir = SearchDirs[I].getDir()->getName(); + if (CheckDir(Dir)) { + if (IsSystem) + *IsSystem = BestPrefixLength ? I >= SystemDirIdx : false; + BestPrefixIsFramework = false; + } + } else if (SearchDirs[I].isFramework()) { + StringRef Dir = SearchDirs[I].getFrameworkDir()->getName(); + if (CheckDir(Dir)) { + if (IsSystem) + *IsSystem = BestPrefixLength ? I >= SystemDirIdx : false; + BestPrefixIsFramework = true; + } + } } // Try to shorten include path using TUs directory, if we couldn't find any // suitable prefix in include search paths. - if (!BestPrefixLength && CheckDir(path::parent_path(MainFile)) && IsSystem) - *IsSystem = false; + if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) { + if (IsSystem) + *IsSystem = false; + BestPrefixIsFramework = false; + } // Try resolving resulting filename via reverse search in header maps, // key from header name is user prefered name for the include file. @@ -1912,8 +1961,19 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics( SearchDirs[I].getHeaderMap()->reverseLookupFilename(Filename); if (!SpelledFilename.empty()) { Filename = SpelledFilename; + BestPrefixIsFramework = false; break; } } + + // If the best prefix is a framework path, we need to compute the proper + // include spelling for the framework header. + bool IsPrivateHeader; + SmallString<128> FrameworkName, IncludeSpelling; + if (BestPrefixIsFramework && + isFrameworkStylePath(Filename, IsPrivateHeader, FrameworkName, + IncludeSpelling)) { + Filename = IncludeSpelling; + } return path::convert_to_slash(Filename); } diff --git contrib/llvm-project/clang/lib/Frontend/InitHeaderSearch.cpp contrib/llvm-project/clang/lib/Lex/InitHeaderSearch.cpp similarity index 99% rename from contrib/llvm-project/clang/lib/Frontend/InitHeaderSearch.cpp rename to contrib/llvm-project/clang/lib/Lex/InitHeaderSearch.cpp index ed1314f3b03d..ec7b1505c7bf 100644 --- contrib/llvm-project/clang/lib/Frontend/InitHeaderSearch.cpp +++ contrib/llvm-project/clang/lib/Lex/InitHeaderSearch.cpp @@ -10,11 +10,10 @@ // //===----------------------------------------------------------------------===// +#include "clang/Basic/DiagnosticFrontend.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" #include "clang/Config/config.h" // C_INCLUDE_DIRS -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Frontend/Utils.h" #include "clang/Lex/HeaderMap.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/HeaderSearchOptions.h" @@ -354,7 +353,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, break; case llvm::Triple::PS4: { // <isysroot> gets prepended later in AddPath(). - std::string BaseSDKPath = ""; + std::string BaseSDKPath; if (!HasSysroot) { const char *envValue = getenv("SCE_ORBIS_SDK_DIR"); if (envValue) diff --git contrib/llvm-project/clang/lib/Lex/Lexer.cpp contrib/llvm-project/clang/lib/Lex/Lexer.cpp index 38467a1835d0..89e89c7c1f17 100644 --- contrib/llvm-project/clang/lib/Lex/Lexer.cpp +++ contrib/llvm-project/clang/lib/Lex/Lexer.cpp @@ -2548,9 +2548,9 @@ static bool isEndOfBlockCommentWithEscapedNewLine(const char *CurPtr, assert(CurPtr[0] == '\n' || CurPtr[0] == '\r'); // Position of the first trigraph in the ending sequence. - const char *TrigraphPos = 0; + const char *TrigraphPos = nullptr; // Position of the first whitespace after a '\' in the ending sequence. - const char *SpacePos = 0; + const char *SpacePos = nullptr; while (true) { // Back up off the newline. diff --git contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp index ef7a5351953e..f3aefdd22b51 100644 --- contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp +++ contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp @@ -818,10 +818,13 @@ Preprocessor::getHeaderToIncludeForDiagnostics(SourceLocation IncLoc, Optional<FileEntryRef> Preprocessor::LookupFile( SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const FileEntry *FromFile, - const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath, + const DirectoryLookup **CurDirArg, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache) { + const DirectoryLookup *CurDirLocal = nullptr; + const DirectoryLookup *&CurDir = CurDirArg ? *CurDirArg : CurDirLocal; + Module *RequestingModule = getModuleForLocation(FilenameLoc); bool RequestingModuleIsModuleInterface = !SourceMgr.isInMainFile(FilenameLoc); @@ -877,7 +880,7 @@ Optional<FileEntryRef> Preprocessor::LookupFile( const DirectoryLookup *TmpCurDir = CurDir; const DirectoryLookup *TmpFromDir = nullptr; while (Optional<FileEntryRef> FE = HeaderInfo.LookupFile( - Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir, + Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir, Includers, SearchPath, RelativePath, RequestingModule, SuggestedModule, /*IsMapped=*/nullptr, /*IsFrameworkFound=*/nullptr, SkipCache)) { @@ -895,7 +898,7 @@ Optional<FileEntryRef> Preprocessor::LookupFile( // Do a standard file entry lookup. Optional<FileEntryRef> FE = HeaderInfo.LookupFile( - Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath, + Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath, RelativePath, RequestingModule, SuggestedModule, IsMapped, IsFrameworkFound, SkipCache, BuildSystemModule); if (FE) { @@ -1827,7 +1830,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, } Optional<FileEntryRef> Preprocessor::LookupHeaderIncludeOrImport( - const DirectoryLookup *&CurDir, StringRef& Filename, + const DirectoryLookup **CurDir, StringRef& Filename, SourceLocation FilenameLoc, CharSourceRange FilenameRange, const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl, bool &IsMapped, const DirectoryLookup *LookupFrom, @@ -2028,7 +2031,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport( } Optional<FileEntryRef> File = LookupHeaderIncludeOrImport( - CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok, + &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok, IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile, LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled); @@ -2055,7 +2058,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport( // include cycle. Don't enter already processed files again as it can lead to // reaching the max allowed include depth again. if (Action == Enter && HasReachedMaxIncludeDepth && File && - HeaderInfo.getFileInfo(&File->getFileEntry()).NumIncludes) + alreadyIncluded(*File)) Action = IncludeLimitReached; // Determine whether we should try to import the module for this #include, if diff --git contrib/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp contrib/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp index cfee7a3c2513..f6c95a8b67c6 100644 --- contrib/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp +++ contrib/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp @@ -1228,10 +1228,9 @@ static bool EvaluateHasIncludeCommon(Token &Tok, return false; // Search include directories. - const DirectoryLookup *CurDir; Optional<FileEntryRef> File = PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile, - CurDir, nullptr, nullptr, nullptr, nullptr, nullptr); + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (PPCallbacks *Callbacks = PP.getPPCallbacks()) { SrcMgr::CharacteristicKind FileType = SrcMgr::C_User; diff --git contrib/llvm-project/clang/lib/Lex/Pragma.cpp contrib/llvm-project/clang/lib/Lex/Pragma.cpp index 67daa5841983..eb7e7cbc4714 100644 --- contrib/llvm-project/clang/lib/Lex/Pragma.cpp +++ contrib/llvm-project/clang/lib/Lex/Pragma.cpp @@ -526,9 +526,8 @@ static llvm::Optional<Token> LexHeader(Preprocessor &PP, return llvm::None; // Search include directories for this file. - const DirectoryLookup *CurDir; File = PP.LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr, - nullptr, CurDir, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (!File) { if (!SuppressIncludeNotFoundError) diff --git contrib/llvm-project/clang/lib/Lex/Preprocessor.cpp contrib/llvm-project/clang/lib/Lex/Preprocessor.cpp index b026ae36fc0f..3c338a2b8123 100644 --- contrib/llvm-project/clang/lib/Lex/Preprocessor.cpp +++ contrib/llvm-project/clang/lib/Lex/Preprocessor.cpp @@ -549,7 +549,7 @@ void Preprocessor::EnterMainSourceFile() { // Tell the header info that the main file was entered. If the file is later // #imported, it won't be re-entered. if (const FileEntry *FE = SourceMgr.getFileEntryForID(MainFileID)) - HeaderInfo.IncrementIncludeCount(FE); + markIncluded(FE); } // Preprocess Predefines to populate the initial preprocessor state. @@ -566,11 +566,10 @@ void Preprocessor::EnterMainSourceFile() { if (!PPOpts->PCHThroughHeader.empty()) { // Lookup and save the FileID for the through header. If it isn't found // in the search path, it's a fatal error. - const DirectoryLookup *CurDir; Optional<FileEntryRef> File = LookupFile( SourceLocation(), PPOpts->PCHThroughHeader, - /*isAngled=*/false, /*FromDir=*/nullptr, /*FromFile=*/nullptr, CurDir, - /*SearchPath=*/nullptr, /*RelativePath=*/nullptr, + /*isAngled=*/false, /*FromDir=*/nullptr, /*FromFile=*/nullptr, + /*CurDir=*/nullptr, /*SearchPath=*/nullptr, /*RelativePath=*/nullptr, /*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr, /*IsFrameworkFound=*/nullptr); if (!File) { diff --git contrib/llvm-project/clang/lib/Parse/ParseCXXInlineMethods.cpp contrib/llvm-project/clang/lib/Parse/ParseCXXInlineMethods.cpp index 19cddc69ebfc..7330c2b7593d 100644 --- contrib/llvm-project/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -140,8 +140,22 @@ NamedDecl *Parser::ParseCXXInlineMethodDef( // function body. if (ConsumeAndStoreFunctionPrologue(Toks)) { // We didn't find the left-brace we expected after the - // constructor initializer; we already printed an error, and it's likely - // impossible to recover, so don't try to parse this method later. + // constructor initializer. + + // If we're code-completing and the completion point was in the broken + // initializer, we want to parse it even though that will fail. + if (PP.isCodeCompletionEnabled() && + llvm::any_of(Toks, [](const Token &Tok) { + return Tok.is(tok::code_completion); + })) { + // If we gave up at the completion point, the initializer list was + // likely truncated, so don't eat more tokens. We'll hit some extra + // errors, but they should be ignored in code completion. + return FnD; + } + + // We already printed an error, and it's likely impossible to recover, + // so don't try to parse this method later. // Skip over the rest of the decl and back to somewhere that looks // reasonable. SkipMalformedDecl(); @@ -803,7 +817,7 @@ bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, // We always want this function to consume at least one token if the first // token isn't T and if not at EOF. bool isFirstTokenConsumed = true; - while (1) { + while (true) { // If we found one of the tokens, stop and return true. if (Tok.is(T1) || Tok.is(T2)) { if (ConsumeFinalToken) { @@ -1159,7 +1173,7 @@ bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks, unsigned AngleCount = 0; unsigned KnownTemplateCount = 0; - while (1) { + while (true) { switch (Tok.getKind()) { case tok::comma: // If we might be in a template, perform a tentative parse to check. diff --git contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp index 0c1f88bc51d1..f21938c81689 100644 --- contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp @@ -2419,8 +2419,9 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl); auto RunSignatureHelp = [&]() { QualType PreferredType = Actions.ProduceConstructorSignatureHelp( - getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(), - ThisDecl->getLocation(), Exprs, T.getOpenLocation()); + ThisVarDecl->getType()->getCanonicalTypeInternal(), + ThisDecl->getLocation(), Exprs, T.getOpenLocation(), + /*Braced=*/false); CalledSignatureHelp = true; return PreferredType; }; @@ -2439,8 +2440,9 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( if (ParseExpressionList(Exprs, CommaLocs, ExpressionStarts)) { if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) { Actions.ProduceConstructorSignatureHelp( - getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(), - ThisDecl->getLocation(), Exprs, T.getOpenLocation()); + ThisVarDecl->getType()->getCanonicalTypeInternal(), + ThisDecl->getLocation(), Exprs, T.getOpenLocation(), + /*Braced=*/false); CalledSignatureHelp = true; } Actions.ActOnInitializerError(ThisDecl); @@ -3078,7 +3080,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, ParsedAttributesWithRange attrs(AttrFactory); // We use Sema's policy to get bool macros right. PrintingPolicy Policy = Actions.getPrintingPolicy(); - while (1) { + while (true) { bool isInvalid = false; bool isStorageClass = false; const char *PrevSpec = nullptr; @@ -3574,12 +3576,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, } } ConsumedEnd = Tok.getLocation(); + DS.setTypeofParensRange(Tracker.getRange()); // Even if something went wrong above, continue as if we've seen // `decltype(auto)`. isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec, DiagID, TemplateId, Policy); } else { - isInvalid = DS.SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID, + isInvalid = DS.SetTypeSpecType(TST_auto, AutoLoc, PrevSpec, DiagID, TemplateId, Policy); } break; @@ -4269,7 +4272,7 @@ void Parser::ParseStructDeclaration( // Read struct-declarators until we find the semicolon. bool FirstDeclarator = true; SourceLocation CommaLoc; - while (1) { + while (true) { ParsingFieldDeclarator DeclaratorInfo(*this, DS); DeclaratorInfo.D.setCommaLoc(CommaLoc); @@ -4536,7 +4539,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, CXXScopeSpec Spec; if (ParseOptionalCXXScopeSpecifier(Spec, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/true)) return; @@ -5420,7 +5423,7 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide) { // Parse the C++ scope specifier. CXXScopeSpec SS; if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/true)) { TPA.Revert(); return false; @@ -5578,7 +5581,7 @@ void Parser::ParseTypeQualifierListOpt( SourceLocation EndLoc; - while (1) { + while (true) { bool isInvalid = false; const char *PrevSpec = nullptr; unsigned DiagID = 0; @@ -5802,7 +5805,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D, D.getContext() == DeclaratorContext::Member; CXXScopeSpec SS; ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, EnteringContext); + /*ObjectHasErrors=*/false, EnteringContext); if (SS.isNotEmpty()) { if (Tok.isNot(tok::star)) { @@ -6031,7 +6034,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { D.getContext() == DeclaratorContext::Member; ParseOptionalCXXScopeSpecifier( D.getCXXScopeSpec(), /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, EnteringContext); + /*ObjectHasErrors=*/false, EnteringContext); } if (D.getCXXScopeSpec().isValid()) { @@ -6270,7 +6273,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { if (D.hasName() && !D.getNumTypeObjects()) MaybeParseCXX11Attributes(D); - while (1) { + while (true) { if (Tok.is(tok::l_paren)) { bool IsFunctionDeclaration = D.isFunctionDeclaratorAFunctionDeclaration(); // Enter function-declaration scope, limiting any declarators to the diff --git contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp index f5a6ffcff9e9..c08a586604b1 100644 --- contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp @@ -291,7 +291,7 @@ Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, CXXScopeSpec SS; // Parse (optional) nested-name-specifier. ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false, /*MayBePseudoDestructor=*/nullptr, /*IsTypename=*/false, @@ -529,7 +529,7 @@ Decl *Parser::ParseUsingDirective(DeclaratorContext Context, CXXScopeSpec SS; // Parse (optional) nested-name-specifier. ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false, /*MayBePseudoDestructor=*/nullptr, /*IsTypename=*/false, @@ -598,7 +598,7 @@ bool Parser::ParseUsingDeclarator(DeclaratorContext Context, // Parse nested-name-specifier. IdentifierInfo *LastII = nullptr; if (ParseOptionalCXXScopeSpecifier(D.SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false, /*MayBePseudoDtor=*/nullptr, /*IsTypename=*/false, @@ -1007,6 +1007,9 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { if (Tok.is(tok::annot_decltype)) { Result = getExprAnnotation(Tok); EndLoc = Tok.getAnnotationEndLoc(); + // Unfortunately, we don't know the LParen source location as the annotated + // token doesn't have it. + DS.setTypeofParensRange(SourceRange(SourceLocation(), EndLoc)); ConsumeAnnotationToken(); if (Result.isInvalid()) { DS.SetTypeSpecError(); @@ -1071,6 +1074,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { // Match the ')' T.consumeClose(); + DS.setTypeofParensRange(T.getRange()); if (T.getCloseLocation().isInvalid()) { DS.SetTypeSpecError(); // FIXME: this should return the location of the last token @@ -1190,7 +1194,7 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, // Parse optional nested-name-specifier CXXScopeSpec SS; if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false)) return true; @@ -1609,7 +1613,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, CXXScopeSpec Spec; bool HasValidSpec = true; if (ParseOptionalCXXScopeSpecifier(Spec, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, EnteringContext)) { DS.SetTypeSpecError(); HasValidSpec = false; @@ -2605,7 +2609,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // Collect the scope specifier token we annotated earlier. CXXScopeSpec SS; ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); if (SS.isInvalid()) { @@ -2905,7 +2909,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // member-declarator // member-declarator-list ',' member-declarator - while (1) { + while (true) { InClassInitStyle HasInClassInit = ICIS_NoInit; bool HasStaticInitializer = false; if (Tok.isOneOf(tok::equal, tok::l_brace) && PureSpecLoc.isInvalid()) { @@ -3674,7 +3678,7 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { // parse '::'[opt] nested-name-specifier[opt] CXXScopeSpec SS; if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false)) return true; @@ -3740,8 +3744,8 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { if (TemplateTypeTy.isInvalid()) return QualType(); QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp( - getCurScope(), ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II, - T.getOpenLocation()); + ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II, + T.getOpenLocation(), /*Braced=*/false); CalledSignatureHelp = true; return PreferredType; }; diff --git contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp index 09a3842f5809..fbf79a0a8746 100644 --- contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp @@ -400,7 +400,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { SourceLocation ColonLoc; auto SavedType = PreferredType; - while (1) { + while (true) { // Every iteration may rely on a preferred type for the whole expression. PreferredType = SavedType; // If this token has a lower precedence than we are allowed to parse (e.g. @@ -1588,7 +1588,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, // cast expression. CXXScopeSpec SS; ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); AnnotateTemplateIdTokenAsType(SS); return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, @@ -1853,7 +1853,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // parsed, see if there are any postfix-expression pieces here. SourceLocation Loc; auto SavedType = PreferredType; - while (1) { + while (true) { // Each iteration relies on preferred type for the whole expression. PreferredType = SavedType; switch (Tok.getKind()) { @@ -2019,7 +2019,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { CommaLocsTy CommaLocs; auto RunSignatureHelp = [&]() -> QualType { QualType PreferredType = Actions.ProduceCallSignatureHelp( - getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation()); + LHS.get(), ArgExprs, PT.getOpenLocation()); CalledSignatureHelp = true; return PreferredType; }; @@ -2558,7 +2558,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); // FIXME: This loop leaks the index expressions on error. - while (1) { + while (true) { if (Tok.is(tok::period)) { // offsetof-member-designator: offsetof-member-designator '.' identifier Comps.push_back(Sema::OffsetOfComponent()); @@ -3358,7 +3358,7 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, SmallVectorImpl<SourceLocation> &CommaLocs, llvm::function_ref<void()> ExpressionStarts) { bool SawError = false; - while (1) { + while (true) { if (ExpressionStarts) ExpressionStarts(); @@ -3418,7 +3418,7 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, bool Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs, SmallVectorImpl<SourceLocation> &CommaLocs) { - while (1) { + while (true) { ExprResult Expr = ParseAssignmentExpression(); if (Expr.isInvalid()) return true; diff --git contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp index 76c510ddd36c..2d38891c723f 100644 --- contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp @@ -668,7 +668,7 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { // CXXScopeSpec SS; ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); Token Replacement; @@ -1877,8 +1877,8 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { QualType PreferredType; if (TypeRep) PreferredType = Actions.ProduceConstructorSignatureHelp( - getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DS.getEndLoc(), Exprs, T.getOpenLocation()); + TypeRep.get()->getCanonicalTypeInternal(), DS.getEndLoc(), Exprs, + T.getOpenLocation(), /*Braced=*/false); CalledSignatureHelp = true; return PreferredType; }; @@ -1953,6 +1953,9 @@ Parser::ParseAliasDeclarationInInitStatement(DeclaratorContext Context, /// \param Loc The location of the start of the statement that requires this /// condition, e.g., the "for" in a for loop. /// +/// \param MissingOK Whether an empty condition is acceptable here. Otherwise +/// it is considered an error to be recovered from. +/// /// \param FRI If non-null, a for range declaration is permitted, and if /// present will be parsed and stored here, and a null result will be returned. /// @@ -1960,11 +1963,10 @@ Parser::ParseAliasDeclarationInInitStatement(DeclaratorContext Context, /// appropriate moment for a 'for' loop. /// /// \returns The parsed condition. -Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, - SourceLocation Loc, - Sema::ConditionKind CK, - ForRangeInfo *FRI, - bool EnterForConditionScope) { +Sema::ConditionResult +Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc, + Sema::ConditionKind CK, bool MissingOK, + ForRangeInfo *FRI, bool EnterForConditionScope) { // Helper to ensure we always enter a continue/break scope if requested. struct ForConditionScopeRAII { Scope *S; @@ -2019,7 +2021,7 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, } ConsumeToken(); *InitStmt = Actions.ActOnNullStmt(SemiLoc); - return ParseCXXCondition(nullptr, Loc, CK); + return ParseCXXCondition(nullptr, Loc, CK, MissingOK); } // Parse the expression. @@ -2031,10 +2033,11 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, WarnOnInit(); *InitStmt = Actions.ActOnExprStmt(Expr.get()); ConsumeToken(); - return ParseCXXCondition(nullptr, Loc, CK); + return ParseCXXCondition(nullptr, Loc, CK, MissingOK); } - return Actions.ActOnCondition(getCurScope(), Loc, Expr.get(), CK); + return Actions.ActOnCondition(getCurScope(), Loc, Expr.get(), CK, + MissingOK); } case ConditionOrInitStatement::InitStmtDecl: { @@ -2048,7 +2051,7 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, DG = ParseSimpleDeclaration(DeclaratorContext::SelectionInit, DeclEnd, attrs, /*RequireSemi=*/true); *InitStmt = Actions.ActOnDeclStmt(DG, DeclStart, DeclEnd); - return ParseCXXCondition(nullptr, Loc, CK); + return ParseCXXCondition(nullptr, Loc, CK, MissingOK); } case ConditionOrInitStatement::ForRangeDecl: { @@ -2454,8 +2457,8 @@ bool Parser::ParseUnqualifiedIdTemplateId( // Parse the enclosed template argument list. SourceLocation LAngleLoc, RAngleLoc; TemplateArgList TemplateArgs; - if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs, - RAngleLoc)) + if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs, RAngleLoc, + Template)) return true; // If this is a non-template, we already issued a diagnostic. @@ -3167,8 +3170,9 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { // `new decltype(invalid) (^)`. if (TypeRep) PreferredType = Actions.ProduceConstructorSignatureHelp( - getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen); + TypeRep.get()->getCanonicalTypeInternal(), + DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen, + /*Braced=*/false); CalledSignatureHelp = true; return PreferredType; }; @@ -3585,7 +3589,7 @@ ExprResult Parser::ParseRequiresExpression() { // We need to consume the typename to allow 'requires { typename a; }' SourceLocation TypenameKWLoc = ConsumeToken(); - if (TryAnnotateCXXScopeToken()) { + if (TryAnnotateOptionalCXXScopeToken()) { TPA.Commit(); SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); break; diff --git contrib/llvm-project/clang/lib/Parse/ParseInit.cpp contrib/llvm-project/clang/lib/Parse/ParseInit.cpp index 9d9c03d28a97..fd0faba9c1c1 100644 --- contrib/llvm-project/clang/lib/Parse/ParseInit.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseInit.cpp @@ -459,12 +459,22 @@ ExprResult Parser::ParseBraceInitializer() { Actions, EnterExpressionEvaluationContext::InitList); bool InitExprsOk = true; - DesignatorCompletionInfo DesignatorCompletion{ - InitExprs, - PreferredType.get(T.getOpenLocation()), + QualType LikelyType = PreferredType.get(T.getOpenLocation()); + DesignatorCompletionInfo DesignatorCompletion{InitExprs, LikelyType}; + bool CalledSignatureHelp = false; + auto RunSignatureHelp = [&] { + QualType PreferredType; + if (!LikelyType.isNull()) + PreferredType = Actions.ProduceConstructorSignatureHelp( + LikelyType->getCanonicalTypeInternal(), T.getOpenLocation(), + InitExprs, T.getOpenLocation(), /*Braced=*/true); + CalledSignatureHelp = true; + return PreferredType; }; - while (1) { + while (true) { + PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp); + // Handle Microsoft __if_exists/if_not_exists if necessary. if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) { diff --git contrib/llvm-project/clang/lib/Parse/ParseObjc.cpp contrib/llvm-project/clang/lib/Parse/ParseObjc.cpp index 9e145f57d61f..f493ac9b92ca 100644 --- contrib/llvm-project/clang/lib/Parse/ParseObjc.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseObjc.cpp @@ -134,7 +134,7 @@ Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { SmallVector<SourceLocation, 8> ClassLocs; SmallVector<ObjCTypeParamList *, 8> ClassTypeParams; - while (1) { + while (true) { MaybeSkipAttributes(tok::objc_class); if (expectIdentifier()) { SkipUntil(tok::semi); @@ -598,7 +598,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, SourceRange AtEnd; - while (1) { + while (true) { // If this is a method prototype, parse it. if (Tok.isOneOf(tok::minus, tok::plus)) { if (Decl *methodPrototype = @@ -848,7 +848,7 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); - while (1) { + while (true) { if (Tok.is(tok::code_completion)) { cutOffParsing(); Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS); @@ -1149,7 +1149,7 @@ void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS, assert(Context == DeclaratorContext::ObjCParameter || Context == DeclaratorContext::ObjCResult); - while (1) { + while (true) { if (Tok.is(tok::code_completion)) { cutOffParsing(); Actions.CodeCompleteObjCPassingType( @@ -1401,7 +1401,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, Scope::FunctionDeclarationScope | Scope::DeclScope); AttributePool allParamAttrs(AttrFactory); - while (1) { + while (true) { ParsedAttributes paramAttrs(AttrFactory); Sema::ObjCArgInfo ArgInfo; @@ -1531,7 +1531,7 @@ ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols, SmallVector<IdentifierLocPair, 8> ProtocolIdents; - while (1) { + while (true) { if (Tok.is(tok::code_completion)) { cutOffParsing(); Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents); @@ -2050,7 +2050,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc)); // Parse the list of forward declarations. - while (1) { + while (true) { ConsumeToken(); // the ',' if (expectIdentifier()) { SkipUntil(tok::semi); @@ -3179,7 +3179,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, ExprVector KeyExprs; if (Tok.is(tok::colon)) { - while (1) { + while (true) { // Each iteration parses a single keyword argument. KeyIdents.push_back(selIdent); KeyLocs.push_back(Loc); @@ -3599,7 +3599,7 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { unsigned nColons = 0; if (Tok.isNot(tok::r_paren)) { - while (1) { + while (true) { if (TryConsumeToken(tok::coloncolon)) { // Handle :: in C++. ++nColons; KeyIdents.push_back(nullptr); diff --git contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp index 300b022d83b9..8ad5edb1bcd6 100644 --- contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp @@ -23,6 +23,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/UniqueVector.h" +#include "llvm/Frontend/OpenMP/OMPAssume.h" #include "llvm/Frontend/OpenMP/OMPContext.h" using namespace clang; @@ -469,8 +470,8 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) { SourceLocation LParLoc = T.getOpenLocation(); auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() { QualType PreferredType = Actions.ProduceConstructorSignatureHelp( - getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(), - OmpPrivParm->getLocation(), Exprs, LParLoc); + OmpPrivParm->getType()->getCanonicalTypeInternal(), + OmpPrivParm->getLocation(), Exprs, LParLoc, /*Braced=*/false); CalledSignatureHelp = true; return PreferredType; }; @@ -1813,38 +1814,55 @@ parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) { void Parser::ParseOMPDeclareTargetClauses( Sema::DeclareTargetContextInfo &DTCI) { SourceLocation DeviceTypeLoc; - bool RequiresToOrLinkClause = false; - bool HasToOrLinkClause = false; + bool RequiresToOrLinkOrIndirectClause = false; + bool HasToOrLinkOrIndirectClause = false; while (Tok.isNot(tok::annot_pragma_openmp_end)) { OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To; bool HasIdentifier = Tok.is(tok::identifier); if (HasIdentifier) { // If we see any clause we need a to or link clause. - RequiresToOrLinkClause = true; + RequiresToOrLinkOrIndirectClause = true; IdentifierInfo *II = Tok.getIdentifierInfo(); StringRef ClauseName = II->getName(); bool IsDeviceTypeClause = getLangOpts().OpenMP >= 50 && getOpenMPClauseKind(ClauseName) == OMPC_device_type; + bool IsIndirectClause = getLangOpts().OpenMP >= 51 && + getOpenMPClauseKind(ClauseName) == OMPC_indirect; + if (DTCI.Indirect.hasValue() && IsIndirectClause) { + Diag(Tok, diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(OMPD_declare_target) + << getOpenMPClauseName(OMPC_indirect) << 0; + break; + } bool IsToOrLinkClause = OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT); assert((!IsDeviceTypeClause || !IsToOrLinkClause) && "Cannot be both!"); - if (!IsDeviceTypeClause && DTCI.Kind == OMPD_begin_declare_target) { + if (!IsDeviceTypeClause && !IsIndirectClause && + DTCI.Kind == OMPD_begin_declare_target) { Diag(Tok, diag::err_omp_declare_target_unexpected_clause) - << ClauseName << 0; + << ClauseName << (getLangOpts().OpenMP >= 51 ? 3 : 0); break; } - if (!IsDeviceTypeClause && !IsToOrLinkClause) { + if (!IsDeviceTypeClause && !IsToOrLinkClause && !IsIndirectClause) { Diag(Tok, diag::err_omp_declare_target_unexpected_clause) - << ClauseName << (getLangOpts().OpenMP >= 50 ? 2 : 1); + << ClauseName + << (getLangOpts().OpenMP >= 51 ? 4 + : getLangOpts().OpenMP >= 50 ? 2 + : 1); break; } - if (IsToOrLinkClause) - HasToOrLinkClause = true; + if (IsToOrLinkClause || IsIndirectClause) + HasToOrLinkOrIndirectClause = true; + if (IsIndirectClause) { + if (!ParseOpenMPIndirectClause(DTCI, /*ParseOnly*/ false)) + break; + continue; + } // Parse 'device_type' clause and go to next clause if any. if (IsDeviceTypeClause) { Optional<SimpleClauseData> DevTypeData = @@ -1910,10 +1928,14 @@ void Parser::ParseOMPDeclareTargetClauses( ConsumeToken(); } + if (DTCI.Indirect.hasValue() && DTCI.DT != OMPDeclareTargetDeclAttr::DT_Any) + Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type); + // For declare target require at least 'to' or 'link' to be present. - if (DTCI.Kind == OMPD_declare_target && RequiresToOrLinkClause && - !HasToOrLinkClause) - Diag(DTCI.Loc, diag::err_omp_declare_target_missing_to_or_link_clause); + if (DTCI.Kind == OMPD_declare_target && RequiresToOrLinkOrIndirectClause && + !HasToOrLinkOrIndirectClause) + Diag(DTCI.Loc, diag::err_omp_declare_target_missing_to_or_link_clause) + << (getLangOpts().OpenMP >= 51 ? 1 : 0); SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); } @@ -2188,12 +2210,12 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( VariantMatchInfo VMI; TI.getAsVariantMatchInfo(ASTCtx, VMI); - std::function<void(StringRef)> DiagUnknownTrait = [this, Loc]( - StringRef ISATrait) { - // TODO Track the selector locations in a way that is accessible here to - // improve the diagnostic location. - Diag(Loc, diag::warn_unknown_begin_declare_variant_isa_trait) << ISATrait; - }; + std::function<void(StringRef)> DiagUnknownTrait = + [this, Loc](StringRef ISATrait) { + // TODO Track the selector locations in a way that is accessible here + // to improve the diagnostic location. + Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait; + }; TargetOMPContext OMPCtx( ASTCtx, std::move(DiagUnknownTrait), /* CurrentFunctionDecl */ nullptr, @@ -2282,11 +2304,12 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_declare_target: { SourceLocation DTLoc = ConsumeAnyToken(); bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end); - bool HasImplicitMappings = - DKind == OMPD_begin_declare_target || !HasClauses; Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc); if (HasClauses) ParseOMPDeclareTargetClauses(DTCI); + bool HasImplicitMappings = + DKind == OMPD_begin_declare_target || !HasClauses || + (DTCI.ExplicitlyMapped.empty() && DTCI.Indirect.hasValue()); // Skip the last annot_pragma_openmp_end. ConsumeAnyToken(); @@ -2528,7 +2551,13 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { TPA.Revert(); // End of the first iteration. Parser is reset to the start of metadirective - TargetOMPContext OMPCtx(ASTContext, /* DiagUnknownTrait */ nullptr, + std::function<void(StringRef)> DiagUnknownTrait = + [this, Loc](StringRef ISATrait) { + // TODO Track the selector locations in a way that is accessible here + // to improve the diagnostic location. + Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait; + }; + TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait), /* CurrentFunctionDecl */ nullptr, ArrayRef<llvm::omp::TraitProperty>()); @@ -2936,7 +2965,7 @@ bool Parser::ParseOpenMPSimpleVarList( if (AllowScopeSpecifier && getLangOpts().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, false)) { + /*ObjectHasErrors=*/false, false)) { IsCorrect = false; SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); @@ -3383,6 +3412,47 @@ OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc); } +/// Parse indirect clause for '#pragma omp declare target' directive. +/// 'indirect' '[' '(' invoked-by-fptr ')' ']' +/// where invoked-by-fptr is a constant boolean expression that evaluates to +/// true or false at compile time. +bool Parser::ParseOpenMPIndirectClause(Sema::DeclareTargetContextInfo &DTCI, + bool ParseOnly) { + SourceLocation Loc = ConsumeToken(); + SourceLocation RLoc; + + if (Tok.isNot(tok::l_paren)) { + if (ParseOnly) + return false; + DTCI.Indirect = nullptr; + return true; + } + + ExprResult Val = + ParseOpenMPParensExpr(getOpenMPClauseName(OMPC_indirect), RLoc); + if (Val.isInvalid()) + return false; + + if (ParseOnly) + return false; + + if (!Val.get()->isValueDependent() && !Val.get()->isTypeDependent() && + !Val.get()->isInstantiationDependent() && + !Val.get()->containsUnexpandedParameterPack()) { + ExprResult Ret = Actions.CheckBooleanCondition(Loc, Val.get()); + if (Ret.isInvalid()) + return false; + llvm::APSInt Result; + Ret = Actions.VerifyIntegerConstantExpression(Val.get(), &Result, + Sema::AllowFold); + if (Ret.isInvalid()) + return false; + DTCI.Indirect = Val.get(); + return true; + } + return false; +} + /// Parsing of OpenMP clauses that use an interop-var. /// /// init-clause: @@ -3817,7 +3887,7 @@ bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) { if (getLangOpts().CPlusPlus) ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) { Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier); @@ -4050,7 +4120,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, if (getLangOpts().CPlusPlus) ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); InvalidReductionId = ParseReductionId( *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId); diff --git contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp index 292ab03e8614..ee07775b6346 100644 --- contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp @@ -1068,7 +1068,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { SourceLocation LabelLoc = ConsumeToken(); SmallVector<Decl *, 8> DeclsInGroup; - while (1) { + while (true) { if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected) << tok::identifier; break; @@ -1191,22 +1191,24 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt, Sema::ConditionResult &Cond, SourceLocation Loc, - Sema::ConditionKind CK, + Sema::ConditionKind CK, bool MissingOK, SourceLocation *LParenLoc, SourceLocation *RParenLoc) { BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); + SourceLocation Start = Tok.getLocation(); - if (getLangOpts().CPlusPlus) - Cond = ParseCXXCondition(InitStmt, Loc, CK); - else { + if (getLangOpts().CPlusPlus) { + Cond = ParseCXXCondition(InitStmt, Loc, CK, MissingOK); + } else { ExprResult CondExpr = ParseExpression(); // If required, convert to a boolean value. if (CondExpr.isInvalid()) Cond = Sema::ConditionError(); else - Cond = Actions.ActOnCondition(getCurScope(), Loc, CondExpr.get(), CK); + Cond = Actions.ActOnCondition(getCurScope(), Loc, CondExpr.get(), CK, + MissingOK); } // If the parser was confused by the condition and we don't have a ')', try to @@ -1220,7 +1222,16 @@ bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt, return true; } - // Otherwise the condition is valid or the rparen is present. + if (Cond.isInvalid()) { + ExprResult CondExpr = Actions.CreateRecoveryExpr( + Start, Tok.getLocation() == Start ? Start : PrevTokLocation, {}, + Actions.PreferredConditionType(CK)); + if (!CondExpr.isInvalid()) + Cond = Actions.ActOnCondition(getCurScope(), Loc, CondExpr.get(), CK, + MissingOK); + } + + // Either the condition is valid or the rparen is present. T.consumeClose(); if (LParenLoc != nullptr) { @@ -1404,7 +1415,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc, IsConstexpr ? Sema::ConditionKind::ConstexprIf : Sema::ConditionKind::Boolean, - &LParen, &RParen)) + /*MissingOK=*/false, &LParen, &RParen)) return StmtError(); if (IsConstexpr) @@ -1599,7 +1610,8 @@ StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) { SourceLocation LParen; SourceLocation RParen; if (ParseParenExprOrCondition(&InitStmt, Cond, SwitchLoc, - Sema::ConditionKind::Switch, &LParen, &RParen)) + Sema::ConditionKind::Switch, + /*MissingOK=*/false, &LParen, &RParen)) return StmtError(); StmtResult Switch = Actions.ActOnStartOfSwitchStmt( @@ -1689,7 +1701,8 @@ StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) { SourceLocation LParen; SourceLocation RParen; if (ParseParenExprOrCondition(nullptr, Cond, WhileLoc, - Sema::ConditionKind::Boolean, &LParen, &RParen)) + Sema::ConditionKind::Boolean, + /*MissingOK=*/false, &LParen, &RParen)) return StmtError(); // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if @@ -1780,10 +1793,18 @@ StmtResult Parser::ParseDoStatement() { // A do-while expression is not a condition, so can't have attributes. DiagnoseAndSkipCXX11Attributes(); + SourceLocation Start = Tok.getLocation(); ExprResult Cond = ParseExpression(); // Correct the typos in condition before closing the scope. if (Cond.isUsable()) Cond = Actions.CorrectDelayedTyposInExpr(Cond); + else { + if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace)) + SkipUntil(tok::semi); + Cond = Actions.CreateRecoveryExpr( + Start, Start == Tok.getLocation() ? Start : PrevTokLocation, {}, + Actions.getASTContext().BoolTy); + } T.consumeClose(); DoScope.Exit(); @@ -2038,10 +2059,11 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { // for-range-declaration next. bool MightBeForRangeStmt = !ForRangeInfo.ParsedForRangeDecl(); ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt); - SecondPart = - ParseCXXCondition(nullptr, ForLoc, Sema::ConditionKind::Boolean, - MightBeForRangeStmt ? &ForRangeInfo : nullptr, - /*EnterForConditionScope*/ true); + SecondPart = ParseCXXCondition( + nullptr, ForLoc, Sema::ConditionKind::Boolean, + // FIXME: recovery if we don't see another semi! + /*MissingOK=*/true, MightBeForRangeStmt ? &ForRangeInfo : nullptr, + /*EnterForConditionScope*/ true); if (ForRangeInfo.ParsedForRangeDecl()) { Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc() @@ -2065,9 +2087,9 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { if (SecondExpr.isInvalid()) SecondPart = Sema::ConditionError(); else - SecondPart = - Actions.ActOnCondition(getCurScope(), ForLoc, SecondExpr.get(), - Sema::ConditionKind::Boolean); + SecondPart = Actions.ActOnCondition( + getCurScope(), ForLoc, SecondExpr.get(), + Sema::ConditionKind::Boolean, /*MissingOK=*/true); } } } diff --git contrib/llvm-project/clang/lib/Parse/ParseStmtAsm.cpp contrib/llvm-project/clang/lib/Parse/ParseStmtAsm.cpp index 3e9ce8fd668f..04c3a8700c10 100644 --- contrib/llvm-project/clang/lib/Parse/ParseStmtAsm.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseStmtAsm.cpp @@ -222,7 +222,7 @@ ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks, CXXScopeSpec SS; if (getLangOpts().CPlusPlus) ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); // Require an identifier here. @@ -508,7 +508,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { TokLoc = Tok.getLocation(); ++NumTokensRead; SkippedStartOfLine = false; - } while (1); + } while (true); if (BraceNesting && BraceCount != savedBraceCount) { // __asm without closing brace (this can happen at EOF). @@ -681,7 +681,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { /// asm-qualifier /// asm-qualifier-list asm-qualifier bool Parser::parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ) { - while (1) { + while (true) { const GNUAsmQualifiers::AQ A = getGNUAsmQualifier(Tok); if (A == GNUAsmQualifiers::AQ_unspecified) { if (Tok.isNot(tok::l_paren)) { @@ -810,7 +810,7 @@ StmtResult Parser::ParseAsmStatement(bool &msAsm) { } // Parse the asm-string list for clobbers if present. if (!AteExtraColon && isTokenStringLiteral()) { - while (1) { + while (true) { ExprResult Clobber(ParseAsmStringLiteral(/*ForAsmLabel*/ false)); if (Clobber.isInvalid()) @@ -888,7 +888,7 @@ bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names, if (!isTokenStringLiteral() && Tok.isNot(tok::l_square)) return false; - while (1) { + while (true) { // Read the [id] if present. if (Tok.is(tok::l_square)) { BalancedDelimiterTracker T(*this, tok::l_square); diff --git contrib/llvm-project/clang/lib/Parse/ParseTemplate.cpp contrib/llvm-project/clang/lib/Parse/ParseTemplate.cpp index 45af61a3926a..f875e3bf43e8 100644 --- contrib/llvm-project/clang/lib/Parse/ParseTemplate.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseTemplate.cpp @@ -391,7 +391,7 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo, CXXScopeSpec SS; if (ParseOptionalCXXScopeSpecifier( SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, /*EnteringContext=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false, /*MayBePseudoDestructor=*/nullptr, /*IsTypename=*/false, /*LastII=*/nullptr, /*OnlyNamespace=*/true) || SS.isInvalid()) { @@ -500,7 +500,7 @@ bool Parser::ParseTemplateParameters( bool Parser::ParseTemplateParameterList(const unsigned Depth, SmallVectorImpl<NamedDecl*> &TemplateParams) { - while (1) { + while (true) { if (NamedDecl *TmpParam = ParseTemplateParameter(Depth, TemplateParams.size())) { @@ -715,7 +715,7 @@ bool Parser::TryAnnotateTypeConstraint() { CXXScopeSpec SS; bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope); if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false, /*MayBePseudoDestructor=*/nullptr, // If this is not a type-constraint, then @@ -787,7 +787,7 @@ NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) { bool TypenameKeyword = false; SourceLocation KeyLoc; ParseOptionalCXXScopeSpecifier(TypeConstraintSS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext*/ false); if (Tok.is(tok::annot_template_id)) { // Consume the 'type-constraint'. @@ -1222,7 +1222,6 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation LAngleLoc, return false; } - /// Parses a template-id that after the template name has /// already been parsed. /// @@ -1234,11 +1233,13 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation LAngleLoc, /// token that forms the template-id. Otherwise, we will leave the /// last token in the stream (e.g., so that it can be replaced with an /// annotation token). -bool -Parser::ParseTemplateIdAfterTemplateName(bool ConsumeLastToken, - SourceLocation &LAngleLoc, - TemplateArgList &TemplateArgs, - SourceLocation &RAngleLoc) { +/// +/// \param NameHint is not required, and merely affects code completion. +bool Parser::ParseTemplateIdAfterTemplateName(bool ConsumeLastToken, + SourceLocation &LAngleLoc, + TemplateArgList &TemplateArgs, + SourceLocation &RAngleLoc, + TemplateTy Template) { assert(Tok.is(tok::less) && "Must have already parsed the template-name"); // Consume the '<'. @@ -1251,7 +1252,7 @@ Parser::ParseTemplateIdAfterTemplateName(bool ConsumeLastToken, if (!Tok.isOneOf(tok::greater, tok::greatergreater, tok::greatergreatergreater, tok::greaterequal, tok::greatergreaterequal)) - Invalid = ParseTemplateArgumentList(TemplateArgs); + Invalid = ParseTemplateArgumentList(TemplateArgs, Template, LAngleLoc); if (Invalid) { // Try to find the closing '>'. @@ -1332,8 +1333,8 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, TemplateArgList TemplateArgs; bool ArgsInvalid = false; if (!TypeConstraint || Tok.is(tok::less)) { - ArgsInvalid = ParseTemplateIdAfterTemplateName(false, LAngleLoc, - TemplateArgs, RAngleLoc); + ArgsInvalid = ParseTemplateIdAfterTemplateName( + false, LAngleLoc, TemplateArgs, RAngleLoc, Template); // If we couldn't recover from invalid arguments, don't form an annotation // token -- we don't know how much to annotate. // FIXME: This can lead to duplicate diagnostics if we retry parsing this @@ -1467,7 +1468,7 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { // '>', or (in some cases) '>>'. CXXScopeSpec SS; // nested-name-specifier, if present ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); ParsedTemplateArgument Result; @@ -1585,19 +1586,34 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() { /// template-argument-list: [C++ 14.2] /// template-argument /// template-argument-list ',' template-argument -bool -Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) { +/// +/// \param Template is only used for code completion, and may be null. +bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs, + TemplateTy Template, + SourceLocation OpenLoc) { ColonProtectionRAIIObject ColonProtection(*this, false); + auto RunSignatureHelp = [&] { + if (!Template) + return QualType(); + CalledSignatureHelp = true; + return Actions.ProduceTemplateArgumentSignatureHelp(Template, TemplateArgs, + OpenLoc); + }; + do { + PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp); ParsedTemplateArgument Arg = ParseTemplateArgument(); SourceLocation EllipsisLoc; if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc); - if (Arg.isInvalid()) + if (Arg.isInvalid()) { + if (PP.isCodeCompletionReached() && !CalledSignatureHelp) + RunSignatureHelp(); return true; + } // Save this template argument. TemplateArgs.push_back(Arg); diff --git contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp index 35c9036fb27e..512993a5278e 100644 --- contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp +++ contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp @@ -277,7 +277,7 @@ Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) { /// '{' '}' /// Parser::TPResult Parser::TryParseInitDeclaratorList() { - while (1) { + while (true) { // declarator TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); if (TPR != TPResult::Ambiguous) @@ -1068,7 +1068,7 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, if (mayHaveDirectInit) return TPResult::Ambiguous; - while (1) { + while (true) { TPResult TPR(TPResult::Ambiguous); if (Tok.is(tok::l_paren)) { @@ -1898,7 +1898,7 @@ Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration, // parameter-declaration // parameter-declaration-list ',' parameter-declaration // - while (1) { + while (true) { // '...'[opt] if (Tok.is(tok::ellipsis)) { ConsumeToken(); diff --git contrib/llvm-project/clang/lib/Parse/Parser.cpp contrib/llvm-project/clang/lib/Parse/Parser.cpp index 11113fa1a060..ffa1e0f027f1 100644 --- contrib/llvm-project/clang/lib/Parse/Parser.cpp +++ contrib/llvm-project/clang/lib/Parse/Parser.cpp @@ -279,7 +279,7 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) { // We always want this function to skip at least one token if the first token // isn't T and if not at EOF. bool isFirstTokenSkipped = true; - while (1) { + while (true) { // If we found one of the tokens, stop and return true. for (unsigned i = 0, NumToks = Toks.size(); i != NumToks; ++i) { if (Tok.is(Toks[i])) { @@ -1448,7 +1448,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { ParseDeclarator(ParmDeclarator); // Handle the full declarator list. - while (1) { + while (true) { // If attributes are present, parse them. MaybeParseGNUAttributes(ParmDeclarator); @@ -1634,7 +1634,7 @@ Parser::TryAnnotateName(CorrectionCandidateCallback *CCC) { CXXScopeSpec SS; if (getLangOpts().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, EnteringContext)) return ANK_Error; @@ -1882,7 +1882,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() { SourceLocation TypenameLoc = ConsumeToken(); CXXScopeSpec SS; if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false, nullptr, /*IsTypename*/ true)) return true; @@ -1953,7 +1953,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() { CXXScopeSpec SS; if (getLangOpts().CPlusPlus) if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext*/ false)) return true; @@ -2084,7 +2084,7 @@ bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) { CXXScopeSpec SS; if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, EnteringContext)) return true; if (SS.isEmpty()) @@ -2195,7 +2195,7 @@ bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) { // Parse nested-name-specifier. if (getLangOpts().CPlusPlus) ParseOptionalCXXScopeSpecifier(Result.SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); // Check nested-name specifier. diff --git contrib/llvm-project/clang/lib/Rewrite/HTMLRewrite.cpp contrib/llvm-project/clang/lib/Rewrite/HTMLRewrite.cpp index e9b678b69594..70ea2fcd3d04 100644 --- contrib/llvm-project/clang/lib/Rewrite/HTMLRewrite.cpp +++ contrib/llvm-project/clang/lib/Rewrite/HTMLRewrite.cpp @@ -542,7 +542,7 @@ void html::HighlightMacros(Rewriter &R, FileID FID, const Preprocessor& PP) { // Lex all the tokens in raw mode, to avoid entering #includes or expanding // macros. - while (1) { + while (true) { Token Tok; L.LexFromRawLexer(Tok); diff --git contrib/llvm-project/clang/lib/Rewrite/Rewriter.cpp contrib/llvm-project/clang/lib/Rewrite/Rewriter.cpp index 3b06afc76e16..8950bfb7c4dc 100644 --- contrib/llvm-project/clang/lib/Rewrite/Rewriter.cpp +++ contrib/llvm-project/clang/lib/Rewrite/Rewriter.cpp @@ -223,6 +223,7 @@ std::string Rewriter::getRewrittenText(CharSourceRange Range) const { RewriteBuffer::iterator Start = RB.begin(); std::advance(Start, StartOff); RewriteBuffer::iterator End = Start; + assert(EndOff >= StartOff && "Invalid iteration distance"); std::advance(End, EndOff-StartOff); return std::string(Start, End); diff --git contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp index b4dcc9759b99..ac5ad52c0b1d 100644 --- contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -128,7 +128,7 @@ class LogicalErrorHandler : public CFGCallback { Sema &S; public: - LogicalErrorHandler(Sema &S) : CFGCallback(), S(S) {} + LogicalErrorHandler(Sema &S) : S(S) {} static bool HasMacroID(const Expr *E) { if (E->getExprLoc().isMacroID()) diff --git contrib/llvm-project/clang/lib/Sema/CodeCompleteConsumer.cpp contrib/llvm-project/clang/lib/Sema/CodeCompleteConsumer.cpp index 0a2ca54e244a..fefe20941f17 100644 --- contrib/llvm-project/clang/lib/Sema/CodeCompleteConsumer.cpp +++ contrib/llvm-project/clang/lib/Sema/CodeCompleteConsumer.cpp @@ -506,11 +506,92 @@ CodeCompleteConsumer::OverloadCandidate::getFunctionType() const { case CK_FunctionType: return Type; + + case CK_Template: + case CK_Aggregate: + return nullptr; } llvm_unreachable("Invalid CandidateKind!"); } +unsigned CodeCompleteConsumer::OverloadCandidate::getNumParams() const { + if (Kind == CK_Template) + return Template->getTemplateParameters()->size(); + + if (Kind == CK_Aggregate) { + unsigned Count = + std::distance(AggregateType->field_begin(), AggregateType->field_end()); + if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) + Count += CRD->getNumBases(); + return Count; + } + + if (const auto *FT = getFunctionType()) + if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) + return FPT->getNumParams(); + + return 0; +} + +QualType +CodeCompleteConsumer::OverloadCandidate::getParamType(unsigned N) const { + if (Kind == CK_Aggregate) { + if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) { + if (N < CRD->getNumBases()) + return std::next(CRD->bases_begin(), N)->getType(); + N -= CRD->getNumBases(); + } + for (const auto *Field : AggregateType->fields()) + if (N-- == 0) + return Field->getType(); + return QualType(); + } + + if (Kind == CK_Template) { + TemplateParameterList *TPL = getTemplate()->getTemplateParameters(); + if (N < TPL->size()) + if (const auto *D = dyn_cast<NonTypeTemplateParmDecl>(TPL->getParam(N))) + return D->getType(); + return QualType(); + } + + if (const auto *FT = getFunctionType()) + if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) + if (N < FPT->getNumParams()) + return FPT->getParamType(N); + return QualType(); +} + +const NamedDecl * +CodeCompleteConsumer::OverloadCandidate::getParamDecl(unsigned N) const { + if (Kind == CK_Aggregate) { + if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) { + if (N < CRD->getNumBases()) + return std::next(CRD->bases_begin(), N)->getType()->getAsTagDecl(); + N -= CRD->getNumBases(); + } + for (const auto *Field : AggregateType->fields()) + if (N-- == 0) + return Field; + return nullptr; + } + + if (Kind == CK_Template) { + TemplateParameterList *TPL = getTemplate()->getTemplateParameters(); + if (N < TPL->size()) + return TPL->getParam(N); + return nullptr; + } + + // Note that if we only have a FunctionProtoType, we don't have param decls. + if (const auto *FD = getFunction()) { + if (N < FD->param_size()) + return FD->getParamDecl(N); + } + return nullptr; +} + //===----------------------------------------------------------------------===// // Code completion consumer implementation //===----------------------------------------------------------------------===// @@ -645,7 +726,7 @@ static std::string getOverloadAsString(const CodeCompletionString &CCS) { void PrintingCodeCompleteConsumer::ProcessOverloadCandidates( Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates, - unsigned NumCandidates, SourceLocation OpenParLoc) { + unsigned NumCandidates, SourceLocation OpenParLoc, bool Braced) { OS << "OPENING_PAREN_LOC: "; OpenParLoc.print(OS, SemaRef.getSourceManager()); OS << "\n"; @@ -653,7 +734,7 @@ void PrintingCodeCompleteConsumer::ProcessOverloadCandidates( for (unsigned I = 0; I != NumCandidates; ++I) { if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString( CurrentArg, SemaRef, getAllocator(), CCTUInfo, - includeBriefComments())) { + includeBriefComments(), Braced)) { OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n"; } } diff --git contrib/llvm-project/clang/lib/Sema/OpenCLBuiltins.td contrib/llvm-project/clang/lib/Sema/OpenCLBuiltins.td index 38debc5aa9fc..df2f206041c1 100644 --- contrib/llvm-project/clang/lib/Sema/OpenCLBuiltins.td +++ contrib/llvm-project/clang/lib/Sema/OpenCLBuiltins.td @@ -80,11 +80,14 @@ def FuncExtKhrLocalInt32ExtendedAtomics : FunctionExtension<"cl_khr_local_int32 def FuncExtKhrInt64BaseAtomics : FunctionExtension<"cl_khr_int64_base_atomics">; def FuncExtKhrInt64ExtendedAtomics : FunctionExtension<"cl_khr_int64_extended_atomics">; def FuncExtKhrMipmapImage : FunctionExtension<"cl_khr_mipmap_image">; +def FuncExtKhrMipmapImageReadWrite : FunctionExtension<"cl_khr_mipmap_image __opencl_c_read_write_images">; def FuncExtKhrMipmapImageWrites : FunctionExtension<"cl_khr_mipmap_image_writes">; def FuncExtKhrGlMsaaSharing : FunctionExtension<"cl_khr_gl_msaa_sharing">; +def FuncExtKhrGlMsaaSharingReadWrite : FunctionExtension<"cl_khr_gl_msaa_sharing __opencl_c_read_write_images">; def FuncExtOpenCLCPipes : FunctionExtension<"__opencl_c_pipes">; def FuncExtOpenCLCWGCollectiveFunctions : FunctionExtension<"__opencl_c_work_group_collective_functions">; +def FuncExtOpenCLCReadWriteImages : FunctionExtension<"__opencl_c_read_write_images">; def FuncExtFloatAtomicsFp16GlobalLoadStore : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_load_store">; def FuncExtFloatAtomicsFp16LocalLoadStore : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_load_store">; def FuncExtFloatAtomicsFp16GenericLoadStore : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_load_store __opencl_c_ext_fp16_local_atomic_load_store">; @@ -1390,30 +1393,35 @@ foreach coordTy = [Int, Float] in { } // --- Table 23: Sampler-less Read Functions --- +multiclass ImageReadSamplerless<string aQual> { + foreach imgTy = [Image2d, Image1dArray] in { + def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>; + def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>; + def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>; + } + foreach imgTy = [Image3d, Image2dArray] in { + def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>], Attr.Pure>; + def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>], Attr.Pure>; + def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>], Attr.Pure>; + } + foreach imgTy = [Image1d, Image1dBuffer] in { + def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, Int], Attr.Pure>; + def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, Int], Attr.Pure>; + def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Int], Attr.Pure>; + } + def : Builtin<"read_imagef", [Float, ImageType<Image2dDepth, aQual>, VectorType<Int, 2>], Attr.Pure>; + def : Builtin<"read_imagef", [Float, ImageType<Image2dArrayDepth, aQual>, VectorType<Int, 4>], Attr.Pure>; +} + let MinVersion = CL12 in { - foreach aQual = ["RO", "RW"] in { - foreach imgTy = [Image2d, Image1dArray] in { - def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>; - def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>; - def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>; - } - foreach imgTy = [Image3d, Image2dArray] in { - def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>], Attr.Pure>; - def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>], Attr.Pure>; - def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>], Attr.Pure>; - } - foreach imgTy = [Image1d, Image1dBuffer] in { - def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, Int], Attr.Pure>; - def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, Int], Attr.Pure>; - def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Int], Attr.Pure>; - } - def : Builtin<"read_imagef", [Float, ImageType<Image2dDepth, aQual>, VectorType<Int, 2>], Attr.Pure>; - def : Builtin<"read_imagef", [Float, ImageType<Image2dArrayDepth, aQual>, VectorType<Int, 4>], Attr.Pure>; + defm : ImageReadSamplerless<"RO">; + let Extension = FuncExtOpenCLCReadWriteImages in { + defm : ImageReadSamplerless<"RW">; } } // --- Table 24: Image Write Functions --- -foreach aQual = ["WO", "RW"] in { +multiclass ImageWrite<string aQual> { foreach imgTy = [Image2d] in { def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, VectorType<Float, 4>]>; def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, VectorType<Int, 4>]>; @@ -1443,8 +1451,13 @@ foreach aQual = ["WO", "RW"] in { def : Builtin<"write_imagef", [Void, ImageType<Image2dArrayDepth, aQual>, VectorType<Int, 4>, Float]>; } +defm : ImageWrite<"WO">; +let Extension = FuncExtOpenCLCReadWriteImages in { + defm : ImageWrite<"RW">; +} + // --- Table 25: Image Query Functions --- -foreach aQual = ["RO", "WO", "RW"] in { +multiclass ImageQuery<string aQual> { foreach imgTy = [Image1d, Image1dBuffer, Image2d, Image3d, Image1dArray, Image2dArray, Image2dDepth, Image2dArrayDepth] in { @@ -1468,6 +1481,12 @@ foreach aQual = ["RO", "WO", "RW"] in { } } +defm : ImageQuery<"RO">; +defm : ImageQuery<"WO">; +let Extension = FuncExtOpenCLCReadWriteImages in { + defm : ImageQuery<"RW">; +} + // OpenCL extension v2.0 s5.1.9: Built-in Image Read Functions // --- Table 8 --- foreach aQual = ["RO"] in { @@ -1488,7 +1507,7 @@ foreach aQual = ["RO"] in { // OpenCL extension v2.0 s5.1.10: Built-in Image Sampler-less Read Functions // --- Table 9 --- let MinVersion = CL12 in { - foreach aQual = ["RO", "RW"] in { + multiclass ImageReadHalf<string aQual> { foreach name = ["read_imageh"] in { foreach imgTy = [Image2d, Image1dArray] in { def : Builtin<name, [VectorType<Half, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>; @@ -1501,10 +1520,14 @@ let MinVersion = CL12 in { } } } + defm : ImageReadHalf<"RO">; + let Extension = FuncExtOpenCLCReadWriteImages in { + defm : ImageReadHalf<"RW">; + } } // OpenCL extension v2.0 s5.1.11: Built-in Image Write Functions // --- Table 10 --- -foreach aQual = ["WO", "RW"] in { +multiclass ImageWriteHalf<string aQual> { foreach name = ["write_imageh"] in { def : Builtin<name, [Void, ImageType<Image2d, aQual>, VectorType<Int, 2>, VectorType<Half, 4>]>; def : Builtin<name, [Void, ImageType<Image2dArray, aQual>, VectorType<Int, 4>, VectorType<Half, 4>]>; @@ -1515,6 +1538,12 @@ foreach aQual = ["WO", "RW"] in { } } +defm : ImageWriteHalf<"WO">; +let Extension = FuncExtOpenCLCReadWriteImages in { + defm : ImageWriteHalf<"RW">; +} + + //-------------------------------------------------------------------- // OpenCL v2.0 s6.13.15 - Work-group Functions @@ -1688,14 +1717,24 @@ let Extension = FuncExtKhrMipmapImage in { } } } - // Added to section 6.13.14.5 - foreach aQual = ["RO", "WO", "RW"] in { - foreach imgTy = [Image1d, Image2d, Image3d, Image1dArray, Image2dArray, Image2dDepth, Image2dArrayDepth] in { - def : Builtin<"get_image_num_mip_levels", [Int, ImageType<imgTy, aQual>]>; - } +} + +// Added to section 6.13.14.5 +multiclass ImageQueryNumMipLevels<string aQual> { + foreach imgTy = [Image1d, Image2d, Image3d, Image1dArray, Image2dArray, Image2dDepth, Image2dArrayDepth] in { + def : Builtin<"get_image_num_mip_levels", [Int, ImageType<imgTy, aQual>]>; } } +let Extension = FuncExtKhrMipmapImage in { + defm : ImageQueryNumMipLevels<"RO">; + defm : ImageQueryNumMipLevels<"WO">; +} + +let Extension = FuncExtKhrMipmapImageReadWrite in { + defm : ImageQueryNumMipLevels<"RW">; +} + // Write functions are enabled using a separate extension. let Extension = FuncExtKhrMipmapImageWrites in { // Added to section 6.13.14.4. @@ -1734,39 +1773,48 @@ let Extension = FuncExtKhrMipmapImageWrites in { //-------------------------------------------------------------------- // OpenCL Extension v2.0 s18.3 - Creating OpenCL Memory Objects from OpenGL MSAA Textures -let Extension = FuncExtKhrGlMsaaSharing in { - // --- Table 6.13.14.3 --- - foreach aQual = ["RO", "RW"] in { - foreach imgTy = [Image2dMsaa] in { - def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int], Attr.Pure>; - def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int], Attr.Pure>; - def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int], Attr.Pure>; - } - foreach imgTy = [Image2dArrayMsaa] in { - def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int], Attr.Pure>; - def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int], Attr.Pure>; - def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int], Attr.Pure>; - } - foreach name = ["read_imagef"] in { - def : Builtin<name, [Float, ImageType<Image2dMsaaDepth, aQual>, VectorType<Int, 2>, Int], Attr.Pure>; - def : Builtin<name, [Float, ImageType<Image2dArrayMsaaDepth, aQual>, VectorType<Int, 4>, Int], Attr.Pure>; - } - } - - // --- Table 6.13.14.5 --- - foreach aQual = ["RO", "WO", "RW"] in { - foreach imgTy = [Image2dMsaa, Image2dArrayMsaa, Image2dMsaaDepth, Image2dArrayMsaaDepth] in { - foreach name = ["get_image_width", "get_image_height", - "get_image_channel_data_type", "get_image_channel_order", - "get_image_num_samples"] in { - def : Builtin<name, [Int, ImageType<imgTy, aQual>], Attr.Const>; - } - def : Builtin<"get_image_dim", [VectorType<Int, 2>, ImageType<imgTy, aQual>], Attr.Const>; - } - foreach imgTy = [Image2dArrayMsaa, Image2dArrayMsaaDepth] in { - def : Builtin<"get_image_array_size", [Size, ImageType<imgTy, aQual>], Attr.Const>; +// --- Table 6.13.14.3 --- +multiclass ImageReadMsaa<string aQual> { + foreach imgTy = [Image2dMsaa] in { + def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int], Attr.Pure>; + def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int], Attr.Pure>; + def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int], Attr.Pure>; + } + foreach imgTy = [Image2dArrayMsaa] in { + def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int], Attr.Pure>; + def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int], Attr.Pure>; + def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int], Attr.Pure>; + } + foreach name = ["read_imagef"] in { + def : Builtin<name, [Float, ImageType<Image2dMsaaDepth, aQual>, VectorType<Int, 2>, Int], Attr.Pure>; + def : Builtin<name, [Float, ImageType<Image2dArrayMsaaDepth, aQual>, VectorType<Int, 4>, Int], Attr.Pure>; + } +} + +// --- Table 6.13.14.5 --- +multiclass ImageQueryMsaa<string aQual> { + foreach imgTy = [Image2dMsaa, Image2dArrayMsaa, Image2dMsaaDepth, Image2dArrayMsaaDepth] in { + foreach name = ["get_image_width", "get_image_height", + "get_image_channel_data_type", "get_image_channel_order", + "get_image_num_samples"] in { + def : Builtin<name, [Int, ImageType<imgTy, aQual>], Attr.Const>; } + def : Builtin<"get_image_dim", [VectorType<Int, 2>, ImageType<imgTy, aQual>], Attr.Const>; } + foreach imgTy = [Image2dArrayMsaa, Image2dArrayMsaaDepth] in { + def : Builtin<"get_image_array_size", [Size, ImageType<imgTy, aQual>], Attr.Const>; + } +} + +let Extension = FuncExtKhrGlMsaaSharing in { + defm : ImageReadMsaa<"RO">; + defm : ImageQueryMsaa<"RO">; + defm : ImageQueryMsaa<"WO">; +} + +let Extension = FuncExtKhrGlMsaaSharingReadWrite in { + defm : ImageReadMsaa<"RW">; + defm : ImageQueryMsaa<"RW">; } //-------------------------------------------------------------------- diff --git contrib/llvm-project/clang/lib/Sema/Scope.cpp contrib/llvm-project/clang/lib/Sema/Scope.cpp index 51b0b24e57b7..499279a2659d 100644 --- contrib/llvm-project/clang/lib/Sema/Scope.cpp +++ contrib/llvm-project/clang/lib/Sema/Scope.cpp @@ -91,7 +91,7 @@ void Scope::Init(Scope *parent, unsigned flags) { UsingDirectives.clear(); Entity = nullptr; ErrorTrap.reset(); - NRVO.setPointerAndInt(nullptr, 0); + NRVO.setPointerAndInt(nullptr, false); } bool Scope::containedInPrototypeScope() const { diff --git contrib/llvm-project/clang/lib/Sema/Sema.cpp contrib/llvm-project/clang/lib/Sema/Sema.cpp index 734ed0f62ec6..20b4a9a5d4e6 100644 --- contrib/llvm-project/clang/lib/Sema/Sema.cpp +++ contrib/llvm-project/clang/lib/Sema/Sema.cpp @@ -60,6 +60,16 @@ ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); } DarwinSDKInfo * Sema::getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc, StringRef Platform) { + auto *SDKInfo = getDarwinSDKInfoForAvailabilityChecking(); + if (!SDKInfo && !WarnedDarwinSDKInfoMissing) { + Diag(Loc, diag::warn_missing_sdksettings_for_availability_checking) + << Platform; + WarnedDarwinSDKInfoMissing = true; + } + return SDKInfo; +} + +DarwinSDKInfo *Sema::getDarwinSDKInfoForAvailabilityChecking() { if (CachedDarwinSDKInfo) return CachedDarwinSDKInfo->get(); auto SDKInfo = parseDarwinSDKInfo( @@ -71,8 +81,6 @@ Sema::getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc, } if (!SDKInfo) llvm::consumeError(SDKInfo.takeError()); - Diag(Loc, diag::warn_missing_sdksettings_for_availability_checking) - << Platform; CachedDarwinSDKInfo = std::unique_ptr<DarwinSDKInfo>(); return nullptr; } @@ -187,7 +195,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, CodeSegStack(nullptr), FpPragmaStack(FPOptionsOverride()), CurInitSeg(nullptr), VisContext(nullptr), PragmaAttributeCurrentTargetDecl(nullptr), - IsBuildingRecoveryCallExpr(false), Cleanup{}, LateTemplateParser(nullptr), + IsBuildingRecoveryCallExpr(false), LateTemplateParser(nullptr), LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp), StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr), StdCoroutineTraitsCache(nullptr), CXXTypeInfoDecl(nullptr), @@ -324,9 +332,12 @@ void Sema::Initialize() { Context.getTargetInfo().getSupportedOpenCLOpts(), getLangOpts()); addImplicitTypedef("sampler_t", Context.OCLSamplerTy); addImplicitTypedef("event_t", Context.OCLEventTy); - if (getLangOpts().getOpenCLCompatibleVersion() >= 200) { - addImplicitTypedef("clk_event_t", Context.OCLClkEventTy); - addImplicitTypedef("queue_t", Context.OCLQueueTy); + auto OCLCompatibleVersion = getLangOpts().getOpenCLCompatibleVersion(); + if (OCLCompatibleVersion >= 200) { + if (getLangOpts().OpenCLCPlusPlus || getLangOpts().Blocks) { + addImplicitTypedef("clk_event_t", Context.OCLClkEventTy); + addImplicitTypedef("queue_t", Context.OCLQueueTy); + } if (getLangOpts().OpenCLPipes) addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy); addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy)); @@ -394,7 +405,6 @@ void Sema::Initialize() { } } - #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ if (getOpenCLOptions().isSupported(#Ext, getLangOpts())) { \ addImplicitTypedef(#ExtType, Context.Id##Ty); \ @@ -1858,6 +1868,15 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) { if (isUnevaluatedContext() || Ty.isNull()) return; + // The original idea behind checkTypeSupport function is that unused + // declarations can be replaced with an array of bytes of the same size during + // codegen, such replacement doesn't seem to be possible for types without + // constant byte size like zero length arrays. So, do a deep check for SYCL. + if (D && LangOpts.SYCLIsDevice) { + llvm::DenseSet<QualType> Visited; + deepTypeCheckForSYCLDevice(Loc, Visited, D); + } + Decl *C = cast<Decl>(getCurLexicalContext()); // Memcpy operations for structs containing a member with unsupported type @@ -1932,7 +1951,8 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) { }; auto CheckType = [&](QualType Ty, bool IsRetTy = false) { - if (LangOpts.SYCLIsDevice || (LangOpts.OpenMP && LangOpts.OpenMPIsDevice)) + if (LangOpts.SYCLIsDevice || (LangOpts.OpenMP && LangOpts.OpenMPIsDevice) || + LangOpts.CUDAIsDevice) CheckDeviceType(Ty); QualType UnqualTy = Ty.getCanonicalType().getUnqualifiedType(); @@ -2534,6 +2554,11 @@ static bool IsCPUDispatchCPUSpecificMultiVersion(const Expr *E) { bool Sema::tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD, bool ForceComplain, bool (*IsPlausibleResult)(QualType)) { + if (isSFINAEContext()) { + // If this is a SFINAE context, don't try anything that might trigger ADL + // prematurely. + return false; + } SourceLocation Loc = E.get()->getExprLoc(); SourceRange Range = E.get()->getSourceRange(); diff --git contrib/llvm-project/clang/lib/Sema/SemaCXXScopeSpec.cpp contrib/llvm-project/clang/lib/Sema/SemaCXXScopeSpec.cpp index 8cecf6c6ab4f..4781d71080c9 100644 --- contrib/llvm-project/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -881,7 +881,8 @@ bool Sema::ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, TypeLocBuilder TLB; DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T); - DecltypeTL.setNameLoc(DS.getTypeSpecTypeLoc()); + DecltypeTL.setDecltypeLoc(DS.getTypeSpecTypeLoc()); + DecltypeTL.setRParenLoc(DS.getTypeofParensRange().getEnd()); SS.Extend(Context, SourceLocation(), TLB.getTypeLocInContext(Context, T), ColonColonLoc); return false; diff --git contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp index 4e83fa1fffca..c8fb36b8311a 100644 --- contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp @@ -499,7 +499,8 @@ public: 1 /* null byte always written by sprintf */) {} bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, - const char *, unsigned SpecifierLen) override { + const char *, unsigned SpecifierLen, + const TargetInfo &) override { const size_t FieldWidth = computeFieldWidth(FS); const size_t Precision = computePrecision(FS); @@ -1578,11 +1579,26 @@ static ExprResult SemaBuiltinLaunder(Sema &S, CallExpr *TheCall) { return TheCall; } +// Emit an error and return true if the current object format type is in the +// list of unsupported types. +static bool CheckBuiltinTargetNotInUnsupported( + Sema &S, unsigned BuiltinID, CallExpr *TheCall, + ArrayRef<llvm::Triple::ObjectFormatType> UnsupportedObjectFormatTypes) { + llvm::Triple::ObjectFormatType CurObjFormat = + S.getASTContext().getTargetInfo().getTriple().getObjectFormat(); + if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) { + S.Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported) + << TheCall->getSourceRange(); + return true; + } + return false; +} + // Emit an error and return true if the current architecture is not in the list // of supported architectures. static bool -CheckBuiltinTargetSupport(Sema &S, unsigned BuiltinID, CallExpr *TheCall, - ArrayRef<llvm::Triple::ArchType> SupportedArchs) { +CheckBuiltinTargetInSupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, + ArrayRef<llvm::Triple::ArchType> SupportedArchs) { llvm::Triple::ArchType CurArch = S.getASTContext().getTargetInfo().getTriple().getArch(); if (llvm::is_contained(SupportedArchs, CurArch)) @@ -1664,6 +1680,12 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, switch (BuiltinID) { case Builtin::BI__builtin___CFStringMakeConstantString: + // CFStringMakeConstantString is currently not implemented for GOFF (i.e., + // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported + if (CheckBuiltinTargetNotInUnsupported( + *this, BuiltinID, TheCall, + {llvm::Triple::GOFF, llvm::Triple::XCOFF})) + return ExprError(); assert(TheCall->getNumArgs() == 1 && "Wrong # arguments to builtin CFStringMakeConstantString"); if (CheckObjCString(TheCall->getArg(0))) @@ -1698,7 +1720,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BI_interlockedbittestandreset_acq: case Builtin::BI_interlockedbittestandreset_rel: case Builtin::BI_interlockedbittestandreset_nf: - if (CheckBuiltinTargetSupport( + if (CheckBuiltinTargetInSupported( *this, BuiltinID, TheCall, {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64})) return ExprError(); @@ -1711,9 +1733,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BI_bittestandset64: case Builtin::BI_interlockedbittestandreset64: case Builtin::BI_interlockedbittestandset64: - if (CheckBuiltinTargetSupport(*this, BuiltinID, TheCall, - {llvm::Triple::x86_64, llvm::Triple::arm, - llvm::Triple::thumb, llvm::Triple::aarch64})) + if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall, + {llvm::Triple::x86_64, llvm::Triple::arm, + llvm::Triple::thumb, + llvm::Triple::aarch64})) return ExprError(); break; @@ -1750,10 +1773,12 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, return ExprError(); break; case Builtin::BI__builtin_alloca_with_align: + case Builtin::BI__builtin_alloca_with_align_uninitialized: if (SemaBuiltinAllocaWithAlign(TheCall)) return ExprError(); LLVM_FALLTHROUGH; case Builtin::BI__builtin_alloca: + case Builtin::BI__builtin_alloca_uninitialized: Diag(TheCall->getBeginLoc(), diag::warn_alloca) << TheCall->getDirectCallee(); break; @@ -2189,9 +2214,12 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, break; } - // __builtin_elementwise_ceil restricts the element type to floating point + // These builtins restrict the element type to floating point // types only. - case Builtin::BI__builtin_elementwise_ceil: { + case Builtin::BI__builtin_elementwise_ceil: + case Builtin::BI__builtin_elementwise_floor: + case Builtin::BI__builtin_elementwise_roundeven: + case Builtin::BI__builtin_elementwise_trunc: { if (PrepareBuiltinElementwiseMathOneArgCall(TheCall)) return ExprError(); @@ -2232,8 +2260,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, break; } - // __builtin_reduce_xor supports vector of integers only. - case Builtin::BI__builtin_reduce_xor: { + // These builtins support vectors of integers only. + case Builtin::BI__builtin_reduce_xor: + case Builtin::BI__builtin_reduce_or: + case Builtin::BI__builtin_reduce_and: { if (PrepareBuiltinReduceMathOneArgCall(TheCall)) return ExprError(); @@ -3946,23 +3976,39 @@ bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, // Check if each required feature is included for (StringRef F : ReqFeatures) { - if (TI.hasFeature(F)) - continue; - - // If the feature is 64bit, alter the string so it will print better in - // the diagnostic. - if (F == "64bit") - F = "RV64"; - - // Convert features like "zbr" and "experimental-zbr" to "Zbr". - F.consume_front("experimental-"); - std::string FeatureStr = F.str(); - FeatureStr[0] = std::toupper(FeatureStr[0]); + SmallVector<StringRef> ReqOpFeatures; + F.split(ReqOpFeatures, '|'); + bool HasFeature = false; + for (StringRef OF : ReqOpFeatures) { + if (TI.hasFeature(OF)) { + HasFeature = true; + continue; + } + } - // Error message - FeatureMissing = true; - Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_requires_extension) - << TheCall->getSourceRange() << StringRef(FeatureStr); + if (!HasFeature) { + std::string FeatureStrs = ""; + for (StringRef OF : ReqOpFeatures) { + // If the feature is 64bit, alter the string so it will print better in + // the diagnostic. + if (OF == "64bit") + OF = "RV64"; + + // Convert features like "zbr" and "experimental-zbr" to "Zbr". + OF.consume_front("experimental-"); + std::string FeatureStr = OF.str(); + FeatureStr[0] = std::toupper(FeatureStr[0]); + // Combine strings. + FeatureStrs += FeatureStrs == "" ? "" : ", "; + FeatureStrs += "'"; + FeatureStrs += FeatureStr; + FeatureStrs += "'"; + } + // Error message + FeatureMissing = true; + Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_requires_extension) + << TheCall->getSourceRange() << StringRef(FeatureStrs); + } } if (FeatureMissing) @@ -8880,8 +8926,8 @@ public: void handleInvalidMaskType(StringRef MaskType) override; bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, - const char *startSpecifier, - unsigned specifierLen) override; + const char *startSpecifier, unsigned specifierLen, + const TargetInfo &Target) override; bool checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, const char *StartSpecifier, unsigned SpecifierLen, @@ -9140,11 +9186,9 @@ bool CheckPrintfHandler::checkForCStrMembers( return false; } -bool -CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier - &FS, - const char *startSpecifier, - unsigned specifierLen) { +bool CheckPrintfHandler::HandlePrintfSpecifier( + const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, + unsigned specifierLen, const TargetInfo &Target) { using namespace analyze_format_string; using namespace analyze_printf; @@ -9276,6 +9320,15 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier } } + const llvm::Triple &Triple = Target.getTriple(); + if (CS.getKind() == ConversionSpecifier::nArg && + (Triple.isAndroid() || Triple.isOSFuchsia())) { + EmitFormatDiagnostic(S.PDiag(diag::warn_printf_narg_not_supported), + getLocationOfByte(CS.getStart()), + /*IsStringLocation*/ false, + getSpecifierRange(startSpecifier, specifierLen)); + } + // Check for invalid use of field width if (!FS.hasValidFieldWidth()) { HandleInvalidAmount(FS, FS.getFieldWidth(), /* field width */ 0, @@ -14021,7 +14074,7 @@ class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> { const Expr *UsageExpr; SequenceTree::Seq Seq; - Usage() : UsageExpr(nullptr), Seq() {} + Usage() : UsageExpr(nullptr) {} }; struct UsageInfo { @@ -14030,7 +14083,7 @@ class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> { /// Have we issued a diagnostic for this object already? bool Diagnosed; - UsageInfo() : Uses(), Diagnosed(false) {} + UsageInfo() : Diagnosed(false) {} }; using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>; diff --git contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp index 93c07ccc891f..01fdf51c60c3 100644 --- contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp @@ -36,6 +36,7 @@ #include "clang/Sema/Lookup.h" #include "clang/Sema/Overload.h" #include "clang/Sema/ParsedAttr.h" +#include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Sema.h" @@ -98,7 +99,7 @@ private: unsigned SingleDeclIndex; public: - ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) {} + ShadowMapEntry() : SingleDeclIndex(0) {} ShadowMapEntry(const ShadowMapEntry &) = delete; ShadowMapEntry(ShadowMapEntry &&Move) { *this = std::move(Move); } ShadowMapEntry &operator=(const ShadowMapEntry &) = delete; @@ -1437,7 +1438,7 @@ bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const { bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const { if (!IsOrdinaryNonTypeName(ND)) - return 0; + return false; if (const auto *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl())) if (VD->getType()->isIntegralOrEnumerationType()) @@ -1895,6 +1896,7 @@ static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context, Policy.SuppressStrongLifetime = true; Policy.SuppressUnwrittenScope = true; Policy.SuppressScope = true; + Policy.CleanUglifiedParameters = true; return Policy; } @@ -2816,14 +2818,18 @@ formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl, Optional<ArrayRef<QualType>> ObjCSubsts = None); static std::string -FormatFunctionParameter(const PrintingPolicy &Policy, const ParmVarDecl *Param, - bool SuppressName = false, bool SuppressBlock = false, +FormatFunctionParameter(const PrintingPolicy &Policy, + const DeclaratorDecl *Param, bool SuppressName = false, + bool SuppressBlock = false, Optional<ArrayRef<QualType>> ObjCSubsts = None) { // Params are unavailable in FunctionTypeLoc if the FunctionType is invalid. // It would be better to pass in the param Type, which is usually available. // But this case is rare, so just pretend we fell back to int as elsewhere. if (!Param) return "int"; + Decl::ObjCDeclQualifier ObjCQual = Decl::OBJC_TQ_None; + if (const auto *PVD = dyn_cast<ParmVarDecl>(Param)) + ObjCQual = PVD->getObjCDeclQualifier(); bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext()); if (Param->getType()->isDependentType() || !Param->getType()->isBlockPointerType()) { @@ -2832,18 +2838,17 @@ FormatFunctionParameter(const PrintingPolicy &Policy, const ParmVarDecl *Param, std::string Result; if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName) - Result = std::string(Param->getIdentifier()->getName()); + Result = std::string(Param->getIdentifier()->deuglifiedName()); QualType Type = Param->getType(); if (ObjCSubsts) Type = Type.substObjCTypeArgs(Param->getASTContext(), *ObjCSubsts, ObjCSubstitutionContext::Parameter); if (ObjCMethodParam) { - Result = - "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier(), Type); + Result = "(" + formatObjCParamQualifiers(ObjCQual, Type); Result += Type.getAsString(Policy) + ")"; if (Param->getIdentifier() && !SuppressName) - Result += Param->getIdentifier()->getName(); + Result += Param->getIdentifier()->deuglifiedName(); } else { Type.getAsStringInternal(Result, Policy); } @@ -2871,20 +2876,19 @@ FormatFunctionParameter(const PrintingPolicy &Policy, const ParmVarDecl *Param, // for the block; just use the parameter type as a placeholder. std::string Result; if (!ObjCMethodParam && Param->getIdentifier()) - Result = std::string(Param->getIdentifier()->getName()); + Result = std::string(Param->getIdentifier()->deuglifiedName()); QualType Type = Param->getType().getUnqualifiedType(); if (ObjCMethodParam) { Result = Type.getAsString(Policy); - std::string Quals = - formatObjCParamQualifiers(Param->getObjCDeclQualifier(), Type); + std::string Quals = formatObjCParamQualifiers(ObjCQual, Type); if (!Quals.empty()) Result = "(" + Quals + " " + Result + ")"; if (Result.back() != ')') Result += " "; if (Param->getIdentifier()) - Result += Param->getIdentifier()->getName(); + Result += Param->getIdentifier()->deuglifiedName(); } else { Type.getAsStringInternal(Result, Policy); } @@ -3079,14 +3083,14 @@ static void AddTemplateParameterChunks( if (TTP->getIdentifier()) { PlaceholderStr += ' '; - PlaceholderStr += TTP->getIdentifier()->getName(); + PlaceholderStr += TTP->getIdentifier()->deuglifiedName(); } HasDefaultArg = TTP->hasDefaultArgument(); } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { if (NTTP->getIdentifier()) - PlaceholderStr = std::string(NTTP->getIdentifier()->getName()); + PlaceholderStr = std::string(NTTP->getIdentifier()->deuglifiedName()); NTTP->getType().getAsStringInternal(PlaceholderStr, Policy); HasDefaultArg = NTTP->hasDefaultArgument(); } else { @@ -3098,7 +3102,7 @@ static void AddTemplateParameterChunks( PlaceholderStr = "template<...> class"; if (TTP->getIdentifier()) { PlaceholderStr += ' '; - PlaceholderStr += TTP->getIdentifier()->getName(); + PlaceholderStr += TTP->getIdentifier()->deuglifiedName(); } HasDefaultArg = TTP->hasDefaultArgument(); @@ -3688,6 +3692,31 @@ const RawComment *clang::getParameterComment( return nullptr; } +static void AddOverloadAggregateChunks(const RecordDecl *RD, + const PrintingPolicy &Policy, + CodeCompletionBuilder &Result, + unsigned CurrentArg) { + unsigned ChunkIndex = 0; + auto AddChunk = [&](llvm::StringRef Placeholder) { + if (ChunkIndex > 0) + Result.AddChunk(CodeCompletionString::CK_Comma); + const char *Copy = Result.getAllocator().CopyString(Placeholder); + if (ChunkIndex == CurrentArg) + Result.AddCurrentParameterChunk(Copy); + else + Result.AddPlaceholderChunk(Copy); + ++ChunkIndex; + }; + // Aggregate initialization has all bases followed by all fields. + // (Bases are not legal in C++11 but in that case we never get here). + if (auto *CRD = llvm::dyn_cast<CXXRecordDecl>(RD)) { + for (const auto &Base : CRD->bases()) + AddChunk(Base.getType().getAsString(Policy)); + } + for (const auto &Field : RD->fields()) + AddChunk(FormatFunctionParameter(Policy, Field)); +} + /// Add function overload parameter chunks to the given code completion /// string. static void AddOverloadParameterChunks(ASTContext &Context, @@ -3697,6 +3726,11 @@ static void AddOverloadParameterChunks(ASTContext &Context, CodeCompletionBuilder &Result, unsigned CurrentArg, unsigned Start = 0, bool InOptional = false) { + if (!Function && !Prototype) { + Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "..."); + return; + } + bool FirstParameter = true; unsigned NumParams = Function ? Function->getNumParams() : Prototype->getNumParams(); @@ -3757,10 +3791,83 @@ static void AddOverloadParameterChunks(ASTContext &Context, } } +static std::string +formatTemplateParameterPlaceholder(const NamedDecl *Param, bool &Optional, + const PrintingPolicy &Policy) { + if (const auto *Type = dyn_cast<TemplateTypeParmDecl>(Param)) { + Optional = Type->hasDefaultArgument(); + } else if (const auto *NonType = dyn_cast<NonTypeTemplateParmDecl>(Param)) { + Optional = NonType->hasDefaultArgument(); + } else if (const auto *Template = dyn_cast<TemplateTemplateParmDecl>(Param)) { + Optional = Template->hasDefaultArgument(); + } + std::string Result; + llvm::raw_string_ostream OS(Result); + Param->print(OS, Policy); + return Result; +} + +static std::string templateResultType(const TemplateDecl *TD, + const PrintingPolicy &Policy) { + if (const auto *CTD = dyn_cast<ClassTemplateDecl>(TD)) + return CTD->getTemplatedDecl()->getKindName().str(); + if (const auto *VTD = dyn_cast<VarTemplateDecl>(TD)) + return VTD->getTemplatedDecl()->getType().getAsString(Policy); + if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(TD)) + return FTD->getTemplatedDecl()->getReturnType().getAsString(Policy); + if (isa<TypeAliasTemplateDecl>(TD)) + return "type"; + if (isa<TemplateTemplateParmDecl>(TD)) + return "class"; + if (isa<ConceptDecl>(TD)) + return "concept"; + return ""; +} + +static CodeCompletionString *createTemplateSignatureString( + const TemplateDecl *TD, CodeCompletionBuilder &Builder, unsigned CurrentArg, + const PrintingPolicy &Policy) { + llvm::ArrayRef<NamedDecl *> Params = TD->getTemplateParameters()->asArray(); + CodeCompletionBuilder OptionalBuilder(Builder.getAllocator(), + Builder.getCodeCompletionTUInfo()); + std::string ResultType = templateResultType(TD, Policy); + if (!ResultType.empty()) + Builder.AddResultTypeChunk(Builder.getAllocator().CopyString(ResultType)); + Builder.AddTextChunk( + Builder.getAllocator().CopyString(TD->getNameAsString())); + Builder.AddChunk(CodeCompletionString::CK_LeftAngle); + // Initially we're writing into the main string. Once we see an optional arg + // (with default), we're writing into the nested optional chunk. + CodeCompletionBuilder *Current = &Builder; + for (unsigned I = 0; I < Params.size(); ++I) { + bool Optional = false; + std::string Placeholder = + formatTemplateParameterPlaceholder(Params[I], Optional, Policy); + if (Optional) + Current = &OptionalBuilder; + if (I > 0) + Current->AddChunk(CodeCompletionString::CK_Comma); + Current->AddChunk(I == CurrentArg + ? CodeCompletionString::CK_CurrentParameter + : CodeCompletionString::CK_Placeholder, + Current->getAllocator().CopyString(Placeholder)); + } + // Add the optional chunk to the main string if we ever used it. + if (Current == &OptionalBuilder) + Builder.AddOptionalChunk(OptionalBuilder.TakeString()); + Builder.AddChunk(CodeCompletionString::CK_RightAngle); + // For function templates, ResultType was the function's return type. + // Give some clue this is a function. (Don't show the possibly-bulky params). + if (isa<FunctionTemplateDecl>(TD)) + Builder.AddInformativeChunk("()"); + return Builder.TakeString(); +} + CodeCompletionString * CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( unsigned CurrentArg, Sema &S, CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments) const { + CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments, + bool Braced) const { PrintingPolicy Policy = getCompletionPrintingPolicy(S); // Show signatures of constructors as they are declared: // vector(int n) rather than vector<string>(int n) @@ -3770,22 +3877,20 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( // FIXME: Set priority, availability appropriately. CodeCompletionBuilder Result(Allocator, CCTUInfo, 1, CXAvailability_Available); + + if (getKind() == CK_Template) + return createTemplateSignatureString(getTemplate(), Result, CurrentArg, + Policy); + FunctionDecl *FDecl = getFunction(); const FunctionProtoType *Proto = - dyn_cast<FunctionProtoType>(getFunctionType()); - if (!FDecl && !Proto) { - // Function without a prototype. Just give the return type and a - // highlighted ellipsis. - const FunctionType *FT = getFunctionType(); - Result.AddResultTypeChunk(Result.getAllocator().CopyString( - FT->getReturnType().getAsString(Policy))); - Result.AddChunk(CodeCompletionString::CK_LeftParen); - Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "..."); - Result.AddChunk(CodeCompletionString::CK_RightParen); - return Result.TakeString(); - } + dyn_cast_or_null<FunctionProtoType>(getFunctionType()); - if (FDecl) { + // First, the name/type of the callee. + if (getKind() == CK_Aggregate) { + Result.AddTextChunk( + Result.getAllocator().CopyString(getAggregate()->getName())); + } else if (FDecl) { if (IncludeBriefComments) { if (auto RC = getParameterComment(S.getASTContext(), *this, CurrentArg)) Result.addBriefComment(RC->getBriefText(S.getASTContext())); @@ -3797,14 +3902,21 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( FDecl->getDeclName().print(OS, Policy); Result.AddTextChunk(Result.getAllocator().CopyString(OS.str())); } else { + // Function without a declaration. Just give the return type. Result.AddResultTypeChunk(Result.getAllocator().CopyString( - Proto->getReturnType().getAsString(Policy))); + getFunctionType()->getReturnType().getAsString(Policy))); } - Result.AddChunk(CodeCompletionString::CK_LeftParen); - AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto, Result, - CurrentArg); - Result.AddChunk(CodeCompletionString::CK_RightParen); + // Next, the brackets and parameters. + Result.AddChunk(Braced ? CodeCompletionString::CK_LeftBrace + : CodeCompletionString::CK_LeftParen); + if (getKind() == CK_Aggregate) + AddOverloadAggregateChunks(getAggregate(), Policy, Result, CurrentArg); + else + AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto, Result, + CurrentArg); + Result.AddChunk(Braced ? CodeCompletionString::CK_RightBrace + : CodeCompletionString::CK_RightParen); return Result.TakeString(); } @@ -5408,11 +5520,18 @@ QualType getApproximateType(const Expr *E) { : getApproximateType(CDSME->getBase()); if (CDSME->isArrow() && !Base.isNull()) Base = Base->getPointeeType(); // could handle unique_ptr etc here? - RecordDecl *RD = Base.isNull() ? nullptr : getAsRecordDecl(Base); + auto *RD = + Base.isNull() + ? nullptr + : llvm::dyn_cast_or_null<CXXRecordDecl>(getAsRecordDecl(Base)); if (RD && RD->isCompleteDefinition()) { - for (const auto *Member : RD->lookup(CDSME->getMember())) - if (const ValueDecl *VD = llvm::dyn_cast<ValueDecl>(Member)) - return VD->getType().getNonReferenceType(); + // Look up member heuristically, including in bases. + for (const auto *Member : RD->lookupDependentName( + CDSME->getMember(), [](const NamedDecl *Member) { + return llvm::isa<ValueDecl>(Member); + })) { + return llvm::cast<ValueDecl>(Member)->getType().getNonReferenceType(); + } } } return Unresolved; @@ -5843,36 +5962,37 @@ static QualType getParamType(Sema &SemaRef, // overload candidates. QualType ParamType; for (auto &Candidate : Candidates) { - if (const auto *FType = Candidate.getFunctionType()) - if (const auto *Proto = dyn_cast<FunctionProtoType>(FType)) - if (N < Proto->getNumParams()) { - if (ParamType.isNull()) - ParamType = Proto->getParamType(N); - else if (!SemaRef.Context.hasSameUnqualifiedType( - ParamType.getNonReferenceType(), - Proto->getParamType(N).getNonReferenceType())) - // Otherwise return a default-constructed QualType. - return QualType(); - } + QualType CandidateParamType = Candidate.getParamType(N); + if (CandidateParamType.isNull()) + continue; + if (ParamType.isNull()) { + ParamType = CandidateParamType; + continue; + } + if (!SemaRef.Context.hasSameUnqualifiedType( + ParamType.getNonReferenceType(), + CandidateParamType.getNonReferenceType())) + // Two conflicting types, give up. + return QualType(); } return ParamType; } static QualType -ProduceSignatureHelp(Sema &SemaRef, Scope *S, - MutableArrayRef<ResultCandidate> Candidates, - unsigned CurrentArg, SourceLocation OpenParLoc) { +ProduceSignatureHelp(Sema &SemaRef, MutableArrayRef<ResultCandidate> Candidates, + unsigned CurrentArg, SourceLocation OpenParLoc, + bool Braced) { if (Candidates.empty()) return QualType(); if (SemaRef.getPreprocessor().isCodeCompletionReached()) SemaRef.CodeCompleter->ProcessOverloadCandidates( - SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc); + SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc, + Braced); return getParamType(SemaRef, Candidates, CurrentArg); } -QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, - ArrayRef<Expr *> Args, +QualType Sema::ProduceCallSignatureHelp(Expr *Fn, ArrayRef<Expr *> Args, SourceLocation OpenParLoc) { Fn = unwrapParenList(Fn); if (!CodeCompleter || !Fn) @@ -5969,53 +6089,158 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, } } mergeCandidatesWithResults(*this, Results, CandidateSet, Loc, Args.size()); - QualType ParamType = - ProduceSignatureHelp(*this, S, Results, Args.size(), OpenParLoc); + QualType ParamType = ProduceSignatureHelp(*this, Results, Args.size(), + OpenParLoc, /*Braced=*/false); return !CandidateSet.empty() ? ParamType : QualType(); } -QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type, +// Determine which param to continue aggregate initialization from after +// a designated initializer. +// +// Given struct S { int a,b,c,d,e; }: +// after `S{.b=1,` we want to suggest c to continue +// after `S{.b=1, 2,` we continue with d (this is legal C and ext in C++) +// after `S{.b=1, .a=2,` we continue with b (this is legal C and ext in C++) +// +// Possible outcomes: +// - we saw a designator for a field, and continue from the returned index. +// Only aggregate initialization is allowed. +// - we saw a designator, but it was complex or we couldn't find the field. +// Only aggregate initialization is possible, but we can't assist with it. +// Returns an out-of-range index. +// - we saw no designators, just positional arguments. +// Returns None. +static llvm::Optional<unsigned> +getNextAggregateIndexAfterDesignatedInit(const ResultCandidate &Aggregate, + ArrayRef<Expr *> Args) { + static constexpr unsigned Invalid = std::numeric_limits<unsigned>::max(); + assert(Aggregate.getKind() == ResultCandidate::CK_Aggregate); + + // Look for designated initializers. + // They're in their syntactic form, not yet resolved to fields. + IdentifierInfo *DesignatedFieldName = nullptr; + unsigned ArgsAfterDesignator = 0; + for (const Expr *Arg : Args) { + if (const auto *DIE = dyn_cast<DesignatedInitExpr>(Arg)) { + if (DIE->size() == 1 && DIE->getDesignator(0)->isFieldDesignator()) { + DesignatedFieldName = DIE->getDesignator(0)->getFieldName(); + ArgsAfterDesignator = 0; + } else { + return Invalid; // Complicated designator. + } + } else if (isa<DesignatedInitUpdateExpr>(Arg)) { + return Invalid; // Unsupported. + } else { + ++ArgsAfterDesignator; + } + } + if (!DesignatedFieldName) + return llvm::None; + + // Find the index within the class's fields. + // (Probing getParamDecl() directly would be quadratic in number of fields). + unsigned DesignatedIndex = 0; + const FieldDecl *DesignatedField = nullptr; + for (const auto *Field : Aggregate.getAggregate()->fields()) { + if (Field->getIdentifier() == DesignatedFieldName) { + DesignatedField = Field; + break; + } + ++DesignatedIndex; + } + if (!DesignatedField) + return Invalid; // Designator referred to a missing field, give up. + + // Find the index within the aggregate (which may have leading bases). + unsigned AggregateSize = Aggregate.getNumParams(); + while (DesignatedIndex < AggregateSize && + Aggregate.getParamDecl(DesignatedIndex) != DesignatedField) + ++DesignatedIndex; + + // Continue from the index after the last named field. + return DesignatedIndex + ArgsAfterDesignator + 1; +} + +QualType Sema::ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef<Expr *> Args, - SourceLocation OpenParLoc) { + SourceLocation OpenParLoc, + bool Braced) { if (!CodeCompleter) return QualType(); + SmallVector<ResultCandidate, 8> Results; // A complete type is needed to lookup for constructors. - CXXRecordDecl *RD = - isCompleteType(Loc, Type) ? Type->getAsCXXRecordDecl() : nullptr; + RecordDecl *RD = + isCompleteType(Loc, Type) ? Type->getAsRecordDecl() : nullptr; if (!RD) return Type; + CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD); + + // Consider aggregate initialization. + // We don't check that types so far are correct. + // We also don't handle C99/C++17 brace-elision, we assume init-list elements + // are 1:1 with fields. + // FIXME: it would be nice to support "unwrapping" aggregates that contain + // a single subaggregate, like std::array<T, N> -> T __elements[N]. + if (Braced && !RD->isUnion() && + (!LangOpts.CPlusPlus || (CRD && CRD->isAggregate()))) { + ResultCandidate AggregateSig(RD); + unsigned AggregateSize = AggregateSig.getNumParams(); + + if (auto NextIndex = + getNextAggregateIndexAfterDesignatedInit(AggregateSig, Args)) { + // A designator was used, only aggregate init is possible. + if (*NextIndex >= AggregateSize) + return Type; + Results.push_back(AggregateSig); + return ProduceSignatureHelp(*this, Results, *NextIndex, OpenParLoc, + Braced); + } + + // Describe aggregate initialization, but also constructors below. + if (Args.size() < AggregateSize) + Results.push_back(AggregateSig); + } // FIXME: Provide support for member initializers. // FIXME: Provide support for variadic template constructors. - OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); + if (CRD) { + OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); + for (NamedDecl *C : LookupConstructors(CRD)) { + if (auto *FD = dyn_cast<FunctionDecl>(C)) { + // FIXME: we can't yet provide correct signature help for initializer + // list constructors, so skip them entirely. + if (Braced && LangOpts.CPlusPlus && isInitListConstructor(FD)) + continue; + AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()), Args, + CandidateSet, + /*SuppressUserConversions=*/false, + /*PartialOverloading=*/true, + /*AllowExplicit*/ true); + } else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(C)) { + if (Braced && LangOpts.CPlusPlus && + isInitListConstructor(FTD->getTemplatedDecl())) + continue; - for (NamedDecl *C : LookupConstructors(RD)) { - if (auto *FD = dyn_cast<FunctionDecl>(C)) { - AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()), Args, - CandidateSet, - /*SuppressUserConversions=*/false, - /*PartialOverloading=*/true, - /*AllowExplicit*/ true); - } else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(C)) { - AddTemplateOverloadCandidate( - FTD, DeclAccessPair::make(FTD, C->getAccess()), - /*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet, - /*SuppressUserConversions=*/false, - /*PartialOverloading=*/true); + AddTemplateOverloadCandidate( + FTD, DeclAccessPair::make(FTD, C->getAccess()), + /*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet, + /*SuppressUserConversions=*/false, + /*PartialOverloading=*/true); + } } + mergeCandidatesWithResults(*this, Results, CandidateSet, Loc, Args.size()); } - SmallVector<ResultCandidate, 8> Results; - mergeCandidatesWithResults(*this, Results, CandidateSet, Loc, Args.size()); - return ProduceSignatureHelp(*this, S, Results, Args.size(), OpenParLoc); + return ProduceSignatureHelp(*this, Results, Args.size(), OpenParLoc, Braced); } QualType Sema::ProduceCtorInitMemberSignatureHelp( - Scope *S, Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy, - ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc) { + Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy, + ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc, + bool Braced) { if (!CodeCompleter) return QualType(); @@ -6026,12 +6251,66 @@ QualType Sema::ProduceCtorInitMemberSignatureHelp( // FIXME: Add support for Base class constructors as well. if (ValueDecl *MemberDecl = tryLookupCtorInitMemberDecl( Constructor->getParent(), SS, TemplateTypeTy, II)) - return ProduceConstructorSignatureHelp(getCurScope(), MemberDecl->getType(), + return ProduceConstructorSignatureHelp(MemberDecl->getType(), MemberDecl->getLocation(), ArgExprs, - OpenParLoc); + OpenParLoc, Braced); return QualType(); } +static bool argMatchesTemplateParams(const ParsedTemplateArgument &Arg, + unsigned Index, + const TemplateParameterList &Params) { + const NamedDecl *Param; + if (Index < Params.size()) + Param = Params.getParam(Index); + else if (Params.hasParameterPack()) + Param = Params.asArray().back(); + else + return false; // too many args + + switch (Arg.getKind()) { + case ParsedTemplateArgument::Type: + return llvm::isa<TemplateTypeParmDecl>(Param); // constraints not checked + case ParsedTemplateArgument::NonType: + return llvm::isa<NonTypeTemplateParmDecl>(Param); // type not checked + case ParsedTemplateArgument::Template: + return llvm::isa<TemplateTemplateParmDecl>(Param); // signature not checked + } + llvm_unreachable("Unhandled switch case"); +} + +QualType Sema::ProduceTemplateArgumentSignatureHelp( + TemplateTy ParsedTemplate, ArrayRef<ParsedTemplateArgument> Args, + SourceLocation LAngleLoc) { + if (!CodeCompleter || !ParsedTemplate) + return QualType(); + + SmallVector<ResultCandidate, 8> Results; + auto Consider = [&](const TemplateDecl *TD) { + // Only add if the existing args are compatible with the template. + bool Matches = true; + for (unsigned I = 0; I < Args.size(); ++I) { + if (!argMatchesTemplateParams(Args[I], I, *TD->getTemplateParameters())) { + Matches = false; + break; + } + } + if (Matches) + Results.emplace_back(TD); + }; + + TemplateName Template = ParsedTemplate.get(); + if (const auto *TD = Template.getAsTemplateDecl()) { + Consider(TD); + } else if (const auto *OTS = Template.getAsOverloadedTemplate()) { + for (const NamedDecl *ND : *OTS) + if (const auto *TD = llvm::dyn_cast<TemplateDecl>(ND)) + Consider(TD); + } + return ProduceSignatureHelp(*this, Results, Args.size(), LAngleLoc, + /*Braced=*/false); +} + static QualType getDesignatedType(QualType BaseType, const Designation &Desig) { for (unsigned I = 0; I < Desig.getNumDesignators(); ++I) { if (BaseType.isNull()) @@ -6073,7 +6352,15 @@ void Sema::CodeCompleteDesignator(QualType BaseType, CodeCompleter->getCodeCompletionTUInfo(), CCC); Results.EnterNewScope(); - for (const auto *FD : RD->fields()) { + for (const Decl *D : RD->decls()) { + const FieldDecl *FD; + if (auto *IFD = dyn_cast<IndirectFieldDecl>(D)) + FD = IFD->getAnonField(); + else if (auto *DFD = dyn_cast<FieldDecl>(D)) + FD = DFD; + else + continue; + // FIXME: Make use of previous designators to mark any fields before those // inaccessible, and also compute the next initializer priority. ResultBuilder::Result Result(FD, Results.getBasePriority(FD)); diff --git contrib/llvm-project/clang/lib/Sema/SemaConcept.cpp contrib/llvm-project/clang/lib/Sema/SemaConcept.cpp index 466e37831f66..ce99d4848cca 100755 --- contrib/llvm-project/clang/lib/Sema/SemaConcept.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaConcept.cpp @@ -18,7 +18,6 @@ #include "clang/Sema/Template.h" #include "clang/Sema/Overload.h" #include "clang/Sema/Initialization.h" -#include "clang/Sema/SemaInternal.h" #include "clang/AST/ExprConcepts.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/OperatorPrecedence.h" @@ -1058,7 +1057,7 @@ concepts::ExprRequirement::ExprRequirement( concepts::ExprRequirement::ReturnTypeRequirement:: ReturnTypeRequirement(TemplateParameterList *TPL) : - TypeConstraintInfo(TPL, 0) { + TypeConstraintInfo(TPL, false) { assert(TPL->size() == 1); const TypeConstraint *TC = cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint(); @@ -1070,7 +1069,7 @@ ReturnTypeRequirement(TemplateParameterList *TPL) : Constraint->getTemplateArgsAsWritten() && TemplateSpecializationType::anyInstantiationDependentTemplateArguments( Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1)); - TypeConstraintInfo.setInt(Dependent ? 1 : 0); + TypeConstraintInfo.setInt(Dependent ? true : false); } concepts::TypeRequirement::TypeRequirement(TypeSourceInfo *T) : diff --git contrib/llvm-project/clang/lib/Sema/SemaCoroutine.cpp contrib/llvm-project/clang/lib/Sema/SemaCoroutine.cpp index e89cecd08cca..e7e60b7e7daf 100644 --- contrib/llvm-project/clang/lib/Sema/SemaCoroutine.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaCoroutine.cpp @@ -653,7 +653,7 @@ static void checkNoThrow(Sema &S, const Stmt *E, } if (ThrowingDecls.empty()) { // [dcl.fct.def.coroutine]p15 - // The expression co_Âawait promise.final_Âsuspend() shall not be + // The expression co_await promise.final_suspend() shall not be // potentially-throwing ([except.spec]). // // First time seeing an error, emit the error message. @@ -663,32 +663,32 @@ static void checkNoThrow(Sema &S, const Stmt *E, ThrowingDecls.insert(D); } }; - auto SC = E->getStmtClass(); - if (SC == Expr::CXXConstructExprClass) { - auto const *Ctor = cast<CXXConstructExpr>(E)->getConstructor(); + + if (auto *CE = dyn_cast<CXXConstructExpr>(E)) { + CXXConstructorDecl *Ctor = CE->getConstructor(); checkDeclNoexcept(Ctor); // Check the corresponding destructor of the constructor. - checkDeclNoexcept(Ctor->getParent()->getDestructor(), true); - } else if (SC == Expr::CallExprClass || SC == Expr::CXXMemberCallExprClass || - SC == Expr::CXXOperatorCallExprClass) { - if (!cast<CallExpr>(E)->isTypeDependent()) { - checkDeclNoexcept(cast<CallExpr>(E)->getCalleeDecl()); - auto ReturnType = cast<CallExpr>(E)->getCallReturnType(S.getASTContext()); - // Check the destructor of the call return type, if any. - if (ReturnType.isDestructedType() == - QualType::DestructionKind::DK_cxx_destructor) { - const auto *T = - cast<RecordType>(ReturnType.getCanonicalType().getTypePtr()); - checkDeclNoexcept( - dyn_cast<CXXRecordDecl>(T->getDecl())->getDestructor(), true); - } + checkDeclNoexcept(Ctor->getParent()->getDestructor(), /*IsDtor=*/true); + } else if (auto *CE = dyn_cast<CallExpr>(E)) { + if (CE->isTypeDependent()) + return; + + checkDeclNoexcept(CE->getCalleeDecl()); + QualType ReturnType = CE->getCallReturnType(S.getASTContext()); + // Check the destructor of the call return type, if any. + if (ReturnType.isDestructedType() == + QualType::DestructionKind::DK_cxx_destructor) { + const auto *T = + cast<RecordType>(ReturnType.getCanonicalType().getTypePtr()); + checkDeclNoexcept(dyn_cast<CXXRecordDecl>(T->getDecl())->getDestructor(), + /*IsDtor=*/true); + } + } else + for (const auto *Child : E->children()) { + if (!Child) + continue; + checkNoThrow(S, Child, ThrowingDecls); } - } - for (const auto *Child : E->children()) { - if (!Child) - continue; - checkNoThrow(S, Child, ThrowingDecls); - } } bool Sema::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) { @@ -1184,13 +1184,13 @@ bool CoroutineStmtBuilder::makeReturnOnAllocFailure() { "cannot make statement while the promise type is dependent"); // [dcl.fct.def.coroutine]p10 - // If a search for the name get_Âreturn_Âobject_Âon_Âallocation_Âfailure in + // If a search for the name get_return_object_on_allocation_failure in // the scope of the promise type ([class.member.lookup]) finds any // declarations, then the result of a call to an allocation function used to // obtain storage for the coroutine state is assumed to return nullptr if it // fails to obtain storage, ... If the allocation function returns nullptr, // ... and the return value is obtained by a call to - // T::get_Âreturn_Âobject_Âon_Âallocation_Âfailure(), where T is the + // T::get_return_object_on_allocation_failure(), where T is the // promise type. DeclarationName DN = S.PP.getIdentifierInfo("get_return_object_on_allocation_failure"); @@ -1433,10 +1433,10 @@ bool CoroutineStmtBuilder::makeOnFallthrough() { "cannot make statement while the promise type is dependent"); // [dcl.fct.def.coroutine]/p6 - // If searches for the names return_Âvoid and return_Âvalue in the scope of + // If searches for the names return_void and return_value in the scope of // the promise type each find any declarations, the program is ill-formed. - // [Note 1: If return_Âvoid is found, flowing off the end of a coroutine is - // equivalent to a co_Âreturn with no operand. Otherwise, flowing off the end + // [Note 1: If return_void is found, flowing off the end of a coroutine is + // equivalent to a co_return with no operand. Otherwise, flowing off the end // of a coroutine results in undefined behavior ([stmt.return.coroutine]). — // end note] bool HasRVoid, HasRValue; @@ -1529,7 +1529,7 @@ bool CoroutineStmtBuilder::makeOnException() { bool CoroutineStmtBuilder::makeReturnObject() { // [dcl.fct.def.coroutine]p7 - // The expression promise.get_Âreturn_Âobject() is used to initialize the + // The expression promise.get_return_object() is used to initialize the // returned reference or prvalue result object of a call to a coroutine. ExprResult ReturnObject = buildPromiseCall(S, Fn.CoroutinePromise, Loc, "get_return_object", None); @@ -1740,30 +1740,39 @@ ClassTemplateDecl *Sema::lookupCoroutineTraits(SourceLocation KwLoc, return nullptr; } - if (!InStd) { - // Found only in std::experimental. - Diag(KwLoc, diag::warn_deprecated_coroutine_namespace) - << "coroutine_traits"; - } else if (InExp) { - // Found in std and std::experimental. - Diag(KwLoc, - diag::err_mixed_use_std_and_experimental_namespace_for_coroutine); - Diag(KwLoc, diag::warn_deprecated_coroutine_namespace) - << "coroutine_traits"; - return nullptr; - } - // Prefer ::std to std::experimental. auto &Result = InStd ? ResStd : ResExp; CoroTraitsNamespaceCache = InStd ? StdSpace : ExpSpace; // coroutine_traits is required to be a class template. - if (!(StdCoroutineTraitsCache = Result.getAsSingle<ClassTemplateDecl>())) { + StdCoroutineTraitsCache = Result.getAsSingle<ClassTemplateDecl>(); + if (!StdCoroutineTraitsCache) { Result.suppressDiagnostics(); NamedDecl *Found = *Result.begin(); Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits); return nullptr; } + + if (InExp) { + // Found in std::experimental + Diag(KwLoc, diag::warn_deprecated_coroutine_namespace) + << "coroutine_traits"; + ResExp.suppressDiagnostics(); + auto *Found = *ResExp.begin(); + Diag(Found->getLocation(), diag::note_entity_declared_at) << Found; + + if (InStd && + StdCoroutineTraitsCache != ResExp.getAsSingle<ClassTemplateDecl>()) { + // Also found something different in std + Diag(KwLoc, + diag::err_mixed_use_std_and_experimental_namespace_for_coroutine); + Diag(StdCoroutineTraitsCache->getLocation(), + diag::note_entity_declared_at) + << StdCoroutineTraitsCache; + + return nullptr; + } + } } Namespace = CoroTraitsNamespaceCache; return StdCoroutineTraitsCache; diff --git contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp index 3c58f1d19c04..3252671991b7 100644 --- contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp @@ -1586,10 +1586,13 @@ void Sema::FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, /// We've determined that \p New is a redeclaration of \p Old. Check that they /// have compatible owning modules. bool Sema::CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old) { - // FIXME: The Modules TS is not clear about how friend declarations are - // to be treated. It's not meaningful to have different owning modules for - // linkage in redeclarations of the same entity, so for now allow the - // redeclaration and change the owning modules to match. + // [module.interface]p7: + // A declaration is attached to a module as follows: + // - If the declaration is a non-dependent friend declaration that nominates a + // function with a declarator-id that is a qualified-id or template-id or that + // nominates a class other than with an elaborated-type-specifier with neither + // a nested-name-specifier nor a simple-template-id, it is attached to the + // module to which the friend is attached ([basic.link]). if (New->getFriendObjectKind() && Old->getOwningModuleForLinkage() != New->getOwningModuleForLinkage()) { New->setLocalOwningModule(Old->getOwningModule()); @@ -1628,6 +1631,52 @@ bool Sema::CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old) { return false; } +// [module.interface]p6: +// A redeclaration of an entity X is implicitly exported if X was introduced by +// an exported declaration; otherwise it shall not be exported. +bool Sema::CheckRedeclarationExported(NamedDecl *New, NamedDecl *Old) { + // [module.interface]p1: + // An export-declaration shall inhabit a namespace scope. + // + // So it is meaningless to talk about redeclaration which is not at namespace + // scope. + if (!New->getLexicalDeclContext() + ->getNonTransparentContext() + ->isFileContext() || + !Old->getLexicalDeclContext() + ->getNonTransparentContext() + ->isFileContext()) + return false; + + bool IsNewExported = New->isInExportDeclContext(); + bool IsOldExported = Old->isInExportDeclContext(); + + // It should be irrevelant if both of them are not exported. + if (!IsNewExported && !IsOldExported) + return false; + + if (IsOldExported) + return false; + + assert(IsNewExported); + + Diag(New->getLocation(), diag::err_redeclaration_non_exported) << New; + Diag(Old->getLocation(), diag::note_previous_declaration); + return true; +} + +// A wrapper function for checking the semantic restrictions of +// a redeclaration within a module. +bool Sema::CheckRedeclarationInModule(NamedDecl *New, NamedDecl *Old) { + if (CheckRedeclarationModuleOwnership(New, Old)) + return true; + + if (CheckRedeclarationExported(New, Old)) + return true; + + return false; +} + static bool isUsingDecl(NamedDecl *D) { return isa<UsingShadowDecl>(D) || isa<UnresolvedUsingTypenameDecl>(D) || @@ -3390,7 +3439,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, } } - if (CheckRedeclarationModuleOwnership(New, Old)) + if (CheckRedeclarationInModule(New, Old)) return true; if (!getLangOpts().CPlusPlus) { @@ -4269,7 +4318,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { return New->setInvalidDecl(); } - if (CheckRedeclarationModuleOwnership(New, Old)) + if (CheckRedeclarationInModule(New, Old)) return; // Variables with external linkage are analyzed in FinalizeDeclaratorGroup. @@ -5759,7 +5808,15 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, else if (isa<BlockDecl>(Cur)) Diag(Loc, diag::err_invalid_declarator_in_block) << Name << SS.getRange(); - else + else if (isa<ExportDecl>(Cur)) { + if (!isa<NamespaceDecl>(DC)) + Diag(Loc, diag::err_export_non_namespace_scope_name) + << Name << SS.getRange(); + else + // The cases that DC is not NamespaceDecl should be handled in + // CheckRedeclarationExported. + return false; + } else Diag(Loc, diag::err_invalid_declarator_scope) << Name << cast<NamedDecl>(Cur) << cast<NamedDecl>(DC) << SS.getRange(); @@ -7798,8 +7855,6 @@ void Sema::CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl, DeclarationName Name = R.getLookupName(); // Emit warning and note. - if (getSourceManager().isInSystemMacro(R.getNameLoc())) - return; ShadowedDeclKind Kind = computeShadowedDeclKind(ShadowedDecl, OldDC); Diag(R.getNameLoc(), WarningDiag) << Name << Kind << OldDC; if (!CaptureLoc.isInvalid()) @@ -9128,6 +9183,13 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_virtual_in_union); NewFD->setInvalidDecl(); } + if ((Parent->isClass() || Parent->isStruct()) && + Parent->hasAttr<SYCLSpecialClassAttr>() && + NewFD->getKind() == Decl::Kind::CXXMethod && + NewFD->getName() == "__init" && D.isFunctionDefinition()) { + if (auto *Def = Parent->getDefinition()) + Def->setInitMethod(true); + } } SetNestedNameSpecifier(*this, NewFD, D); @@ -9921,7 +9983,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, << NewFD; // Turn this into a variadic function with no parameters. - const FunctionType *FT = NewFD->getType()->getAs<FunctionType>(); + const auto *FT = NewFD->getType()->castAs<FunctionType>(); FunctionProtoType::ExtProtoInfo EPI( Context.getDefaultCallingConvention(true, false)); EPI.Variadic = true; @@ -14632,8 +14694,10 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, Diag(FD->getLocation(), diag::ext_pure_function_definition); if (!FD->isInvalidDecl()) { - // Don't diagnose unused parameters of defaulted or deleted functions. - if (!FD->isDeleted() && !FD->isDefaulted() && !FD->hasSkippedBody()) + // Don't diagnose unused parameters of defaulted, deleted or naked + // functions. + if (!FD->isDeleted() && !FD->isDefaulted() && !FD->hasSkippedBody() && + !FD->hasAttr<NakedAttr>()) DiagnoseUnusedParameters(FD->parameters()); DiagnoseSizeOfParametersAndReturnValue(FD->parameters(), FD->getReturnType(), FD); @@ -15002,7 +15066,24 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, diag_id = diag::ext_implicit_function_decl; else diag_id = diag::warn_implicit_function_decl; + + TypoCorrection Corrected; + // Because typo correction is expensive, only do it if the implicit + // function declaration is going to be treated as an error. + // + // Perform the corection before issuing the main diagnostic, as some consumers + // use typo-correction callbacks to enhance the main diagnostic. + if (S && !ExternCPrev && + (Diags.getDiagnosticLevel(diag_id, Loc) >= DiagnosticsEngine::Error)) { + DeclFilterCCC<FunctionDecl> CCC{}; + Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc), LookupOrdinaryName, + S, nullptr, CCC, CTK_NonError); + } + Diag(Loc, diag_id) << &II; + if (Corrected) + diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion), + /*ErrorRecovery*/ false); // If we found a prior declaration of this function, don't bother building // another one. We've already pushed that one into scope, so there's nothing @@ -15010,18 +15091,6 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, if (ExternCPrev) return ExternCPrev; - // Because typo correction is expensive, only do it if the implicit - // function declaration is going to be treated as an error. - if (Diags.getDiagnosticLevel(diag_id, Loc) >= DiagnosticsEngine::Error) { - TypoCorrection Corrected; - DeclFilterCCC<FunctionDecl> CCC{}; - if (S && (Corrected = - CorrectTypo(DeclarationNameInfo(&II, Loc), LookupOrdinaryName, - S, nullptr, CCC, CTK_NonError))) - diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion), - /*ErrorRecovery*/false); - } - // Set a Declarator for the implicit definition: int foo(); const char *Dummy; AttributeFactory attrFactory; @@ -15191,11 +15260,11 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation())); - // We make "fma" on some platforms const because we know it does not set + // We make "fma" on GNU or Windows const because we know it does not set // errno in those environments even though it could set errno based on the // C standard. const llvm::Triple &Trip = Context.getTargetInfo().getTriple(); - if ((Trip.isGNUEnvironment() || Trip.isAndroid() || Trip.isOSMSVCRT()) && + if ((Trip.isGNUEnvironment() || Trip.isOSMSVCRT()) && !FD->hasAttr<ConstAttr>()) { switch (BuiltinID) { case Builtin::BI__builtin_fma: @@ -16532,7 +16601,7 @@ CreateNewDecl: SetMemberAccessSpecifier(New, PrevDecl, AS); if (PrevDecl) - CheckRedeclarationModuleOwnership(New, PrevDecl); + CheckRedeclarationInModule(New, PrevDecl); if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) New->startDefinition(); @@ -16682,8 +16751,21 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD, RD->completeDefinition(); } - if (isa<CXXRecordDecl>(Tag)) { + if (auto *RD = dyn_cast<CXXRecordDecl>(Tag)) { FieldCollector->FinishClass(); + if (RD->hasAttr<SYCLSpecialClassAttr>()) { + auto *Def = RD->getDefinition(); + assert(Def && "The record is expected to have a completed definition"); + unsigned NumInitMethods = 0; + for (auto *Method : Def->methods()) { + if (!Method->getIdentifier()) + continue; + if (Method->getName() == "__init") + NumInitMethods++; + } + if (NumInitMethods > 1 || !Def->hasInitMethod()) + Diag(RD->getLocation(), diag::err_sycl_special_type_num_init_method); + } } // Exit this scope of this tag's definition. @@ -18586,7 +18668,7 @@ void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name, AttributeCommonInfo Info(AliasName, SourceRange(AliasNameLoc), AttributeCommonInfo::AS_Pragma); AsmLabelAttr *Attr = AsmLabelAttr::CreateImplicit( - Context, AliasName->getName(), /*LiteralLabel=*/true, Info); + Context, AliasName->getName(), /*IsLiteralLabel=*/true, Info); // If a declaration that: // 1) declares a function or a variable diff --git contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp index b6bd2e69629d..f04236ab96c3 100644 --- contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp @@ -2625,37 +2625,53 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { NewII = &S.Context.Idents.get("watchos_app_extension"); if (NewII) { - auto adjustWatchOSVersion = [](VersionTuple Version) -> VersionTuple { - if (Version.empty()) - return Version; - auto Major = Version.getMajor(); - auto NewMajor = Major >= 9 ? Major - 7 : 0; - if (NewMajor >= 2) { - if (Version.getMinor().hasValue()) { - if (Version.getSubminor().hasValue()) - return VersionTuple(NewMajor, Version.getMinor().getValue(), - Version.getSubminor().getValue()); - else - return VersionTuple(NewMajor, Version.getMinor().getValue()); - } - return VersionTuple(NewMajor); + const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking(); + const auto *IOSToWatchOSMapping = + SDKInfo ? SDKInfo->getVersionMapping( + DarwinSDKInfo::OSEnvPair::iOStoWatchOSPair()) + : nullptr; + + auto adjustWatchOSVersion = + [IOSToWatchOSMapping](VersionTuple Version) -> VersionTuple { + if (Version.empty()) + return Version; + auto MinimumWatchOSVersion = VersionTuple(2, 0); + + if (IOSToWatchOSMapping) { + if (auto MappedVersion = IOSToWatchOSMapping->map( + Version, MinimumWatchOSVersion, None)) { + return MappedVersion.getValue(); } + } - return VersionTuple(2, 0); - }; + auto Major = Version.getMajor(); + auto NewMajor = Major >= 9 ? Major - 7 : 0; + if (NewMajor >= 2) { + if (Version.getMinor().hasValue()) { + if (Version.getSubminor().hasValue()) + return VersionTuple(NewMajor, Version.getMinor().getValue(), + Version.getSubminor().getValue()); + else + return VersionTuple(NewMajor, Version.getMinor().getValue()); + } + return VersionTuple(NewMajor); + } - auto NewIntroduced = adjustWatchOSVersion(Introduced.Version); - auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version); - auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version); - - AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr( - ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated, - NewObsoleted, IsUnavailable, Str, IsStrict, Replacement, - Sema::AMK_None, - PriorityModifier + Sema::AP_InferredFromOtherPlatform); - if (NewAttr) - D->addAttr(NewAttr); - } + return MinimumWatchOSVersion; + }; + + auto NewIntroduced = adjustWatchOSVersion(Introduced.Version); + auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version); + auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version); + + AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr( + ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated, + NewObsoleted, IsUnavailable, Str, IsStrict, Replacement, + Sema::AMK_None, + PriorityModifier + Sema::AP_InferredFromOtherPlatform); + if (NewAttr) + D->addAttr(NewAttr); + } } else if (S.Context.getTargetInfo().getTriple().isTvOS()) { // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning // matches before the start of the tvOS platform. @@ -2666,14 +2682,38 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { NewII = &S.Context.Idents.get("tvos_app_extension"); if (NewII) { + const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking(); + const auto *IOSToTvOSMapping = + SDKInfo ? SDKInfo->getVersionMapping( + DarwinSDKInfo::OSEnvPair::iOStoTvOSPair()) + : nullptr; + + auto AdjustTvOSVersion = + [IOSToTvOSMapping](VersionTuple Version) -> VersionTuple { + if (Version.empty()) + return Version; + + if (IOSToTvOSMapping) { + if (auto MappedVersion = + IOSToTvOSMapping->map(Version, VersionTuple(0, 0), None)) { + return MappedVersion.getValue(); + } + } + return Version; + }; + + auto NewIntroduced = AdjustTvOSVersion(Introduced.Version); + auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version); + auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version); + AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr( - ND, AL, NewII, true /*Implicit*/, Introduced.Version, - Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, IsStrict, - Replacement, Sema::AMK_None, + ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated, + NewObsoleted, IsUnavailable, Str, IsStrict, Replacement, + Sema::AMK_None, PriorityModifier + Sema::AP_InferredFromOtherPlatform); if (NewAttr) D->addAttr(NewAttr); - } + } } else if (S.Context.getTargetInfo().getTriple().getOS() == llvm::Triple::IOS && S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()) { @@ -8261,6 +8301,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_SYCLKernel: handleSYCLKernelAttr(S, D, AL); break; + case ParsedAttr::AT_SYCLSpecialClass: + handleSimpleAttribute<SYCLSpecialClassAttr>(S, D, AL); + break; case ParsedAttr::AT_Format: handleFormatAttr(S, D, AL); break; diff --git contrib/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp contrib/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp index 01f0079198c7..16cdb7e57723 100644 --- contrib/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp @@ -13012,7 +13012,7 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, AccessSpecifier AS, NewDecl->setInvalidDecl(); else if (OldDecl) { NewDecl->setPreviousDecl(OldDecl); - CheckRedeclarationModuleOwnership(NewDecl, OldDecl); + CheckRedeclarationInModule(NewDecl, OldDecl); } NewND = NewDecl; diff --git contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp index d6e659e17069..d4fefc3d18d8 100644 --- contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp @@ -2212,9 +2212,8 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count); } -static void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc, - ObjCMethodDecl *method, - bool &IncompleteImpl, +static void WarnUndefinedMethod(Sema &S, ObjCImplDecl *Impl, + ObjCMethodDecl *method, bool &IncompleteImpl, unsigned DiagID, NamedDecl *NeededFor = nullptr) { // No point warning no definition of method which is 'unavailable'. @@ -2227,10 +2226,19 @@ static void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc, // separate warnings. We will give that approach a try, as that // matches what we do with protocols. { - const Sema::SemaDiagnosticBuilder &B = S.Diag(ImpLoc, DiagID); + const Sema::SemaDiagnosticBuilder &B = S.Diag(Impl->getLocation(), DiagID); B << method; if (NeededFor) B << NeededFor; + + // Add an empty definition at the end of the @implementation. + std::string FixItStr; + llvm::raw_string_ostream Out(FixItStr); + method->print(Out, Impl->getASTContext().getPrintingPolicy()); + Out << " {\n}\n\n"; + + SourceLocation Loc = Impl->getAtEndRange().getBegin(); + B << FixItHint::CreateInsertion(Loc, FixItStr); } // Issue a note to the original declaration. @@ -2679,14 +2687,10 @@ static void findProtocolsWithExplicitImpls(const ObjCInterfaceDecl *Super, /// CheckProtocolMethodDefs - This routine checks unimplemented methods /// Declared in protocol, and those referenced by it. -static void CheckProtocolMethodDefs(Sema &S, - SourceLocation ImpLoc, - ObjCProtocolDecl *PDecl, - bool& IncompleteImpl, - const Sema::SelectorSet &InsMap, - const Sema::SelectorSet &ClsMap, - ObjCContainerDecl *CDecl, - LazyProtocolNameSet &ProtocolsExplictImpl) { +static void CheckProtocolMethodDefs( + Sema &S, ObjCImplDecl *Impl, ObjCProtocolDecl *PDecl, bool &IncompleteImpl, + const Sema::SelectorSet &InsMap, const Sema::SelectorSet &ClsMap, + ObjCContainerDecl *CDecl, LazyProtocolNameSet &ProtocolsExplictImpl) { ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl); ObjCInterfaceDecl *IDecl = C ? C->getClassInterface() : dyn_cast<ObjCInterfaceDecl>(CDecl); @@ -2773,9 +2777,8 @@ static void CheckProtocolMethodDefs(Sema &S, if (C || MethodInClass->isPropertyAccessor()) continue; unsigned DIAG = diag::warn_unimplemented_protocol_method; - if (!S.Diags.isIgnored(DIAG, ImpLoc)) { - WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, - PDecl); + if (!S.Diags.isIgnored(DIAG, Impl->getLocation())) { + WarnUndefinedMethod(S, Impl, method, IncompleteImpl, DIAG, PDecl); } } } @@ -2796,15 +2799,15 @@ static void CheckProtocolMethodDefs(Sema &S, continue; unsigned DIAG = diag::warn_unimplemented_protocol_method; - if (!S.Diags.isIgnored(DIAG, ImpLoc)) { - WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl); + if (!S.Diags.isIgnored(DIAG, Impl->getLocation())) { + WarnUndefinedMethod(S, Impl, method, IncompleteImpl, DIAG, PDecl); } } } // Check on this protocols's referenced protocols, recursively. for (auto *PI : PDecl->protocols()) - CheckProtocolMethodDefs(S, ImpLoc, PI, IncompleteImpl, InsMap, ClsMap, - CDecl, ProtocolsExplictImpl); + CheckProtocolMethodDefs(S, Impl, PI, IncompleteImpl, InsMap, ClsMap, CDecl, + ProtocolsExplictImpl); } /// MatchAllMethodDeclarations - Check methods declared in interface @@ -2827,7 +2830,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, if (!I->isPropertyAccessor() && !InsMap.count(I->getSelector())) { if (ImmediateClass) - WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl, + WarnUndefinedMethod(*this, IMPDecl, I, IncompleteImpl, diag::warn_undef_method_impl); continue; } else { @@ -2857,7 +2860,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, if (!I->isPropertyAccessor() && !ClsMap.count(I->getSelector())) { if (ImmediateClass) - WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl, + WarnUndefinedMethod(*this, IMPDecl, I, IncompleteImpl, diag::warn_undef_method_impl); } else { ObjCMethodDecl *ImpMethodDecl = @@ -3024,16 +3027,15 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) { for (auto *PI : I->all_referenced_protocols()) - CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), PI, IncompleteImpl, - InsMap, ClsMap, I, ExplicitImplProtocols); + CheckProtocolMethodDefs(*this, IMPDecl, PI, IncompleteImpl, InsMap, + ClsMap, I, ExplicitImplProtocols); } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) { // For extended class, unimplemented methods in its protocols will // be reported in the primary class. if (!C->IsClassExtension()) { for (auto *P : C->protocols()) - CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), P, - IncompleteImpl, InsMap, ClsMap, CDecl, - ExplicitImplProtocols); + CheckProtocolMethodDefs(*this, IMPDecl, P, IncompleteImpl, InsMap, + ClsMap, CDecl, ExplicitImplProtocols); DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, /*SynthesizeProperties=*/false); } diff --git contrib/llvm-project/clang/lib/Sema/SemaExceptionSpec.cpp contrib/llvm-project/clang/lib/Sema/SemaExceptionSpec.cpp index 3af4c6f4bc41..29cb4be7b1ba 100644 --- contrib/llvm-project/clang/lib/Sema/SemaExceptionSpec.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaExceptionSpec.cpp @@ -391,9 +391,8 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { NewProto->getExtProtoInfo().withExceptionSpec(ESI))); } - if (getLangOpts().MSVCCompat && ESI.Type != EST_DependentNoexcept) { - // Allow missing exception specifications in redeclarations as an extension. - DiagID = diag::ext_ms_missing_exception_specification; + if (getLangOpts().MSVCCompat && isDynamicExceptionSpec(ESI.Type)) { + DiagID = diag::ext_missing_exception_specification; ReturnValueOnError = false; } else if (New->isReplaceableGlobalAllocationFunction() && ESI.Type != EST_DependentNoexcept) { @@ -402,6 +401,10 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { DiagID = diag::ext_missing_exception_specification; ReturnValueOnError = false; } else if (ESI.Type == EST_NoThrow) { + // Don't emit any warning for missing 'nothrow' in MSVC. + if (getLangOpts().MSVCCompat) { + return false; + } // Allow missing attribute 'nothrow' in redeclarations, since this is a very // common omission. DiagID = diag::ext_missing_exception_specification; diff --git contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp index d32b3f217aa0..7de43705c2b1 100644 --- contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp @@ -55,7 +55,6 @@ using namespace clang; using namespace sema; -using llvm::RoundingMode; /// Determine whether the use of this declaration is valid, without /// emitting diagnostics. @@ -4500,6 +4499,10 @@ Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, } // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t. + if (isUnevaluatedContext() && ExprKind == UETT_SizeOf && + TInfo->getType()->isVariablyModifiedType()) + TInfo = TransformToPotentiallyEvaluated(TInfo); + return new (Context) UnaryExprOrTypeTraitExpr( ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd()); } @@ -4646,6 +4649,38 @@ static bool isMSPropertySubscriptExpr(Sema &S, Expr *Base) { return isa<MSPropertySubscriptExpr>(BaseNoParens); } +// Returns the type used for LHS[RHS], given one of LHS, RHS is type-dependent. +// Typically this is DependentTy, but can sometimes be more precise. +// +// There are cases when we could determine a non-dependent type: +// - LHS and RHS may have non-dependent types despite being type-dependent +// (e.g. unbounded array static members of the current instantiation) +// - one may be a dependent-sized array with known element type +// - one may be a dependent-typed valid index (enum in current instantiation) +// +// We *always* return a dependent type, in such cases it is DependentTy. +// This avoids creating type-dependent expressions with non-dependent types. +// FIXME: is this important to avoid? See https://reviews.llvm.org/D107275 +static QualType getDependentArraySubscriptType(Expr *LHS, Expr *RHS, + const ASTContext &Ctx) { + assert(LHS->isTypeDependent() || RHS->isTypeDependent()); + QualType LTy = LHS->getType(), RTy = RHS->getType(); + QualType Result = Ctx.DependentTy; + if (RTy->isIntegralOrUnscopedEnumerationType()) { + if (const PointerType *PT = LTy->getAs<PointerType>()) + Result = PT->getPointeeType(); + else if (const ArrayType *AT = LTy->getAsArrayTypeUnsafe()) + Result = AT->getElementType(); + } else if (LTy->isIntegralOrUnscopedEnumerationType()) { + if (const PointerType *PT = RTy->getAs<PointerType>()) + Result = PT->getPointeeType(); + else if (const ArrayType *AT = RTy->getAsArrayTypeUnsafe()) + Result = AT->getElementType(); + } + // Ensure we return a dependent type. + return Result->isDependentType() ? Result : Ctx.DependentTy; +} + ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, Expr *idx, SourceLocation rbLoc) { @@ -4738,8 +4773,9 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, // Build an unanalyzed expression if either operand is type-dependent. if (getLangOpts().CPlusPlus && (base->isTypeDependent() || idx->isTypeDependent())) { - return new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy, - VK_LValue, OK_Ordinary, rbLoc); + return new (Context) ArraySubscriptExpr( + base, idx, getDependentArraySubscriptType(base, idx, getASTContext()), + VK_LValue, OK_Ordinary, rbLoc); } // MSDN, property (C++) @@ -5493,7 +5529,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, if (LHSTy->isDependentType() || RHSTy->isDependentType()) { BaseExpr = LHSExp; IndexExpr = RHSExp; - ResultType = Context.DependentTy; + ResultType = + getDependentArraySubscriptType(LHSExp, RHSExp, getASTContext()); } else if (const PointerType *PTy = LHSTy->getAs<PointerType>()) { BaseExpr = LHSExp; IndexExpr = RHSExp; @@ -7694,8 +7731,7 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, CastExpr = Result.get(); } - if (getLangOpts().CPlusPlus && !castType->isVoidType() && - !getSourceManager().isInSystemMacro(LParenLoc)) + if (getLangOpts().CPlusPlus && !castType->isVoidType()) Diag(LParenLoc, diag::warn_old_style_cast) << CastExpr->getSourceRange(); CheckTollFreeBridgeCast(castType, CastExpr); @@ -15913,7 +15949,7 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, // promoted type and the underlying type are the same except for // signedness. Ask the AST for the correctly corresponding type and see // if that's compatible. - if (!PromoteType.isNull() && + if (!PromoteType.isNull() && !UnderlyingType->isBooleanType() && PromoteType->isUnsignedIntegerType() != UnderlyingType->isUnsignedIntegerType()) { UnderlyingType = @@ -16569,6 +16605,16 @@ ExprResult Sema::TransformToPotentiallyEvaluated(Expr *E) { return TransformToPE(*this).TransformExpr(E); } +TypeSourceInfo *Sema::TransformToPotentiallyEvaluated(TypeSourceInfo *TInfo) { + assert(isUnevaluatedContext() && + "Should only transform unevaluated expressions"); + ExprEvalContexts.back().Context = + ExprEvalContexts[ExprEvalContexts.size() - 2].Context; + if (isUnevaluatedContext()) + return TInfo; + return TransformToPE(*this).TransformType(TInfo); +} + void Sema::PushExpressionEvaluationContext( ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl, @@ -19176,10 +19222,12 @@ ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E, } Sema::ConditionResult Sema::ActOnCondition(Scope *S, SourceLocation Loc, - Expr *SubExpr, ConditionKind CK) { - // Empty conditions are valid in for-statements. + Expr *SubExpr, ConditionKind CK, + bool MissingOK) { + // MissingOK indicates whether having no condition expression is valid + // (for loop) or invalid (e.g. while loop). if (!SubExpr) - return ConditionResult(); + return MissingOK ? ConditionResult() : ConditionError(); ExprResult Cond; switch (CK) { @@ -19197,7 +19245,7 @@ Sema::ConditionResult Sema::ActOnCondition(Scope *S, SourceLocation Loc, } if (Cond.isInvalid()) { Cond = CreateRecoveryExpr(SubExpr->getBeginLoc(), SubExpr->getEndLoc(), - {SubExpr}); + {SubExpr}, PreferredConditionType(CK)); if (!Cond.get()) return ConditionError(); } diff --git contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp index 54f0242d2ca1..b34b744d7312 100644 --- contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp @@ -6614,7 +6614,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, const Type *ClassOrBound; Step(Kind K, const Type *ClassOrBound = nullptr) - : K(K), Quals(), ClassOrBound(ClassOrBound) {} + : K(K), ClassOrBound(ClassOrBound) {} QualType rebuild(ASTContext &Ctx, QualType T) const { T = Ctx.getQualifiedType(T, Quals); switch (K) { @@ -7410,8 +7410,10 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, // the member function body. if (!BaseType->isDependentType() && !isThisOutsideMemberFunctionBody(BaseType) && - RequireCompleteType(OpLoc, BaseType, diag::err_incomplete_member_access)) - return ExprError(); + RequireCompleteType(OpLoc, BaseType, + diag::err_incomplete_member_access)) { + return CreateRecoveryExpr(Base->getBeginLoc(), Base->getEndLoc(), {Base}); + } // C++ [basic.lookup.classref]p2: // If the id-expression in a class member access (5.2.5) is an @@ -7767,7 +7769,8 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, TypeLocBuilder TLB; DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T); - DecltypeTL.setNameLoc(DS.getTypeSpecTypeLoc()); + DecltypeTL.setDecltypeLoc(DS.getTypeSpecTypeLoc()); + DecltypeTL.setRParenLoc(DS.getTypeofParensRange().getEnd()); TypeSourceInfo *DestructedTypeInfo = TLB.getTypeSourceInfo(Context, T); PseudoDestructorTypeStorage Destructed(DestructedTypeInfo); @@ -8697,7 +8700,7 @@ Sema::ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS, if (TypeName) { QualType T = CheckTypenameType(ETK_Typename, TypenameKWLoc, SS.getWithLocInContext(Context), *TypeName, - NameLoc, &TSI, /*DeducedTypeContext=*/false); + NameLoc, &TSI, /*DeducedTSTContext=*/false); if (T.isNull()) return nullptr; } else { @@ -8748,7 +8751,7 @@ Sema::ActOnCompoundRequirement( /*HasTypeConstraint=*/true); if (BuildTypeConstraint(SS, TypeConstraint, TParam, - /*EllpsisLoc=*/SourceLocation(), + /*EllipsisLoc=*/SourceLocation(), /*AllowUnexpandedPack=*/true)) // Just produce a requirement with no type requirements. return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc, {}); diff --git contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp index 83006f9d804a..dfd93aa4638d 100644 --- contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp @@ -504,9 +504,12 @@ Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType, } } - assert(BaseType->isDependentType() || - NameInfo.getName().isDependentName() || - isDependentScopeSpecifier(SS)); + assert(BaseType->isDependentType() || NameInfo.getName().isDependentName() || + isDependentScopeSpecifier(SS) || + (TemplateArgs && llvm::any_of(TemplateArgs->arguments(), + [](const TemplateArgumentLoc &Arg) { + return Arg.getArgument().isDependent(); + }))); // Get the type being accessed in BaseType. If this is an arrow, the BaseExpr // must have pointer type, and the accessed type is the pointee. @@ -1642,6 +1645,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange() << FixItHint::CreateReplacement(OpLoc, "->"); + if (S.isSFINAEContext()) + return ExprError(); + // Recurse as an -> access. IsArrow = true; return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, diff --git contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp index bdc8e1e0b336..4702c405fb4e 100644 --- contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp @@ -1280,11 +1280,11 @@ static ObjCMethodDecl *findMethodInCurrentClass(Sema &S, Selector Sel) { // whether Sel is potentially direct in this context. if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/true)) return MD; - if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*isInstance=*/true)) + if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/true)) return MD; if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/false)) return MD; - if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*isInstance=*/false)) + if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/false)) return MD; return nullptr; diff --git contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp index 635e93ba8460..af6ee24240ce 100644 --- contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp @@ -620,7 +620,7 @@ void LookupResult::resolveKind() { getSema().diagnoseEquivalentInternalLinkageDeclarations( getNameLoc(), HasNonFunction, EquivalentNonFunctions); - Decls.set_size(N); + Decls.truncate(N); if (HasNonFunction && (HasFunction || HasUnresolved)) Ambiguous = true; @@ -4307,18 +4307,35 @@ void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) { if (!CList.empty() && !CList.back().isResolved()) CList.pop_back(); if (NamedDecl *NewND = Correction.getCorrectionDecl()) { - std::string CorrectionStr = Correction.getAsString(SemaRef.getLangOpts()); - for (TypoResultList::iterator RI = CList.begin(), RIEnd = CList.end(); - RI != RIEnd; ++RI) { - // If the Correction refers to a decl already in the result list, - // replace the existing result if the string representation of Correction - // comes before the current result alphabetically, then stop as there is - // nothing more to be done to add Correction to the candidate set. - if (RI->getCorrectionDecl() == NewND) { - if (CorrectionStr < RI->getAsString(SemaRef.getLangOpts())) - *RI = Correction; - return; - } + auto RI = llvm::find_if(CList, [NewND](const TypoCorrection &TypoCorr) { + return TypoCorr.getCorrectionDecl() == NewND; + }); + if (RI != CList.end()) { + // The Correction refers to a decl already in the list. No insertion is + // necessary and all further cases will return. + + auto IsDeprecated = [](Decl *D) { + while (D) { + if (D->isDeprecated()) + return true; + D = llvm::dyn_cast_or_null<NamespaceDecl>(D->getDeclContext()); + } + return false; + }; + + // Prefer non deprecated Corrections over deprecated and only then + // sort using an alphabetical order. + std::pair<bool, std::string> NewKey = { + IsDeprecated(Correction.getFoundDecl()), + Correction.getAsString(SemaRef.getLangOpts())}; + + std::pair<bool, std::string> PrevKey = { + IsDeprecated(RI->getFoundDecl()), + RI->getAsString(SemaRef.getLangOpts())}; + + if (NewKey < PrevKey) + *RI = Correction; + return; } } if (CList.empty() || Correction.isResolved()) diff --git contrib/llvm-project/clang/lib/Sema/SemaModule.cpp contrib/llvm-project/clang/lib/Sema/SemaModule.cpp index a4b9f3c242c1..747734f2d0ff 100644 --- contrib/llvm-project/clang/lib/Sema/SemaModule.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaModule.cpp @@ -395,7 +395,7 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, // [module.interface]p1: // An export-declaration shall inhabit a namespace scope and appear in the // purview of a module interface unit. - Diag(ExportLoc, diag::err_export_not_in_module_interface); + Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0; } return Import; @@ -527,21 +527,30 @@ Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, // Set this temporarily so we know the export-declaration was braced. D->setRBraceLoc(LBraceLoc); + CurContext->addDecl(D); + PushDeclContext(S, D); + // C++2a [module.interface]p1: // An export-declaration shall appear only [...] in the purview of a module // interface unit. An export-declaration shall not appear directly or // indirectly within [...] a private-module-fragment. if (ModuleScopes.empty() || !ModuleScopes.back().Module->isModulePurview()) { Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0; + D->setInvalidDecl(); + return D; } else if (!ModuleScopes.back().ModuleInterface) { Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1; Diag(ModuleScopes.back().BeginLoc, diag::note_not_module_interface_add_export) << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export "); + D->setInvalidDecl(); + return D; } else if (ModuleScopes.back().Module->Kind == Module::PrivateModuleFragment) { Diag(ExportLoc, diag::err_export_in_private_module_fragment); Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment); + D->setInvalidDecl(); + return D; } for (const DeclContext *DC = CurContext; DC; DC = DC->getLexicalParent()) { @@ -553,7 +562,7 @@ Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, Diag(ND->getLocation(), diag::note_anonymous_namespace); // Don't diagnose internal-linkage declarations in this region. D->setInvalidDecl(); - break; + return D; } // A declaration is exported if it is [...] a namespace-definition @@ -572,10 +581,10 @@ Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, Diag(ExportLoc, diag::err_export_within_export); if (ED->hasBraces()) Diag(ED->getLocation(), diag::note_export); + D->setInvalidDecl(); + return D; } - CurContext->addDecl(D); - PushDeclContext(S, D); D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported); return D; } diff --git contrib/llvm-project/clang/lib/Sema/SemaObjCProperty.cpp contrib/llvm-project/clang/lib/Sema/SemaObjCProperty.cpp index 74c73ace3c5f..118afb81dd72 100644 --- contrib/llvm-project/clang/lib/Sema/SemaObjCProperty.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaObjCProperty.cpp @@ -112,8 +112,8 @@ CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop, return; // Look for a property with the same name. - if (ObjCPropertyDecl *ProtoProp = - Proto->lookup(Prop->getDeclName()).find_first<ObjCPropertyDecl>()) { + if (ObjCPropertyDecl *ProtoProp = Proto->getProperty( + Prop->getIdentifier(), Prop->isInstanceProperty())) { S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true); return; } @@ -231,8 +231,8 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, bool FoundInSuper = false; ObjCInterfaceDecl *CurrentInterfaceDecl = IFace; while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) { - if (ObjCPropertyDecl *SuperProp = - Super->lookup(Res->getDeclName()).find_first<ObjCPropertyDecl>()) { + if (ObjCPropertyDecl *SuperProp = Super->getProperty( + Res->getIdentifier(), Res->isInstanceProperty())) { DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false); FoundInSuper = true; break; diff --git contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp index ba0481874577..ae91a6470471 100644 --- contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp @@ -36,6 +36,7 @@ #include "llvm/ADT/PointerEmbeddedInt.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Frontend/OpenMP/OMPAssume.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" #include <set> @@ -7051,7 +7052,8 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, QualType AdjustedFnType = FD->getType(); if (NumAppendArgs) { - if (isa<FunctionNoProtoType>(FD->getType())) { + const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>(); + if (!PTy) { Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required) << SR; return None; @@ -7069,8 +7071,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR; return None; } - QualType InteropType = QualType(TD->getTypeForDecl(), 0); - auto *PTy = cast<FunctionProtoType>(FD->getType()); + QualType InteropType = Context.getTypeDeclType(TD); if (PTy->isVariadic()) { Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR; return None; @@ -13148,7 +13149,7 @@ StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses, if (FullClause) { if (!VerifyPositiveIntegerConstantInClause( LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false, - /*SuppressExprDigs=*/true) + /*SuppressExprDiags=*/true) .isUsable()) { Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count); Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here) @@ -20761,8 +20762,7 @@ Sema::ActOnOpenMPEndDeclareTargetDirective() { void Sema::ActOnFinishedOpenMPDeclareTargetContext( DeclareTargetContextInfo &DTCI) { for (auto &It : DTCI.ExplicitlyMapped) - ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, - DTCI.DT); + ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI); } NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, @@ -20799,9 +20799,9 @@ NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, return ND; } -void Sema::ActOnOpenMPDeclareTargetName( - NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, - OMPDeclareTargetDeclAttr::DevTypeTy DT) { +void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, + OMPDeclareTargetDeclAttr::MapTypeTy MT, + DeclareTargetContextInfo &DTCI) { assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && "Expected variable, function or function template."); @@ -20818,10 +20818,10 @@ void Sema::ActOnOpenMPDeclareTargetName( auto *VD = cast<ValueDecl>(ND); llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = OMPDeclareTargetDeclAttr::getActiveAttr(VD); - if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DT && + if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DTCI.DT && ActiveAttr.getValue()->getLevel() == Level) { Diag(Loc, diag::err_omp_device_type_mismatch) - << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) + << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT) << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr( ActiveAttr.getValue()->getDevType()); return; @@ -20835,8 +20835,16 @@ void Sema::ActOnOpenMPDeclareTargetName( if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level) return; - auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, Level, - SourceRange(Loc, Loc)); + Expr *IndirectE = nullptr; + bool IsIndirect = false; + if (DTCI.Indirect.hasValue()) { + IndirectE = DTCI.Indirect.getValue(); + if (!IndirectE) + IsIndirect = true; + } + auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( + Context, MT, DTCI.DT, IndirectE, IsIndirect, Level, + SourceRange(Loc, Loc)); ND->addAttr(A); if (ASTMutationListener *ML = Context.getASTMutationListener()) ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); @@ -20927,9 +20935,16 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level) return; DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); + Expr *IndirectE = nullptr; + bool IsIndirect = false; + if (DTCI.Indirect.hasValue()) { + IndirectE = DTCI.Indirect.getValue(); + if (!IndirectE) + IsIndirect = true; + } auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( - Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, Level, - SourceRange(DTCI.Loc, DTCI.Loc)); + Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE, + IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc)); D->addAttr(A); if (ASTMutationListener *ML = Context.getASTMutationListener()) ML->DeclarationMarkedOpenMPDeclareTarget(D, A); diff --git contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp index 42b1340f9a65..483247aaa7c5 100644 --- contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp @@ -2405,9 +2405,8 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType, if (FromType->isObjCObjectPointerType() && ToPointeeType->isVoidType() && !getLangOpts().ObjCAutoRefCount) { ConvertedType = BuildSimilarlyQualifiedPointerType( - FromType->getAs<ObjCObjectPointerType>(), - ToPointeeType, - ToType, Context); + FromType->castAs<ObjCObjectPointerType>(), ToPointeeType, ToType, + Context); return true; } const PointerType *FromTypePtr = FromType->getAs<PointerType>(); @@ -3718,8 +3717,7 @@ compareConversionFunctions(Sema &S, FunctionDecl *Function1, CallingConv Conv2CC = Conv2FuncRet->getCallConv(); CXXMethodDecl *CallOp = Conv2->getParent()->getLambdaCallOperator(); - const FunctionProtoType *CallOpProto = - CallOp->getType()->getAs<FunctionProtoType>(); + const auto *CallOpProto = CallOp->getType()->castAs<FunctionProtoType>(); CallingConv CallOpCC = CallOp->getType()->castAs<FunctionType>()->getCallConv(); @@ -9416,12 +9414,12 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, AddOverloadCandidate( FD, FoundDecl, Args, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, /*AllowExplicit=*/true, - /*AllowExplicitConversions=*/false, ADLCallKind::UsesADL); + /*AllowExplicitConversion=*/false, ADLCallKind::UsesADL); if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) { AddOverloadCandidate( FD, FoundDecl, {Args[1], Args[0]}, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, - /*AllowExplicit=*/true, /*AllowExplicitConversions=*/false, + /*AllowExplicit=*/true, /*AllowExplicitConversion=*/false, ADLCallKind::UsesADL, None, OverloadCandidateParamOrder::Reversed); } } else { @@ -14322,8 +14320,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, FoundDecl = MemExpr->getFoundDecl(); Qualifier = MemExpr->getQualifier(); UnbridgedCasts.restore(); - } else { - UnresolvedMemberExpr *UnresExpr = cast<UnresolvedMemberExpr>(NakedMemExpr); + } else if (auto *UnresExpr = dyn_cast<UnresolvedMemberExpr>(NakedMemExpr)) { Qualifier = UnresExpr->getQualifier(); QualType ObjectType = UnresExpr->getBaseType(); @@ -14436,7 +14433,9 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, } MemExpr = cast<MemberExpr>(MemExprE->IgnoreParens()); - } + } else + // Unimaged NakedMemExpr type. + return ExprError(); QualType ResultType = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultType); diff --git contrib/llvm-project/clang/lib/Sema/SemaSYCL.cpp contrib/llvm-project/clang/lib/Sema/SemaSYCL.cpp index 815463307ecc..f8c713c8545d 100644 --- contrib/llvm-project/clang/lib/Sema/SemaSYCL.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaSYCL.cpp @@ -48,3 +48,101 @@ bool Sema::checkSYCLDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { return DiagKind != SemaDiagnosticBuilder::K_Immediate && DiagKind != SemaDiagnosticBuilder::K_ImmediateWithCallStack; } + +static bool isZeroSizedArray(Sema &SemaRef, QualType Ty) { + if (const auto *CAT = SemaRef.getASTContext().getAsConstantArrayType(Ty)) + return CAT->getSize() == 0; + return false; +} + +void Sema::deepTypeCheckForSYCLDevice(SourceLocation UsedAt, + llvm::DenseSet<QualType> Visited, + ValueDecl *DeclToCheck) { + assert(getLangOpts().SYCLIsDevice && + "Should only be called during SYCL compilation"); + // Emit notes only for the first discovered declaration of unsupported type + // to avoid mess of notes. This flag is to track that error already happened. + bool NeedToEmitNotes = true; + + auto Check = [&](QualType TypeToCheck, const ValueDecl *D) { + bool ErrorFound = false; + if (isZeroSizedArray(*this, TypeToCheck)) { + SYCLDiagIfDeviceCode(UsedAt, diag::err_typecheck_zero_array_size) << 1; + ErrorFound = true; + } + // Checks for other types can also be done here. + if (ErrorFound) { + if (NeedToEmitNotes) { + if (auto *FD = dyn_cast<FieldDecl>(D)) + SYCLDiagIfDeviceCode(FD->getLocation(), + diag::note_illegal_field_declared_here) + << FD->getType()->isPointerType() << FD->getType(); + else + SYCLDiagIfDeviceCode(D->getLocation(), diag::note_declared_at); + } + } + + return ErrorFound; + }; + + // In case we have a Record used do the DFS for a bad field. + SmallVector<const ValueDecl *, 4> StackForRecursion; + StackForRecursion.push_back(DeclToCheck); + + // While doing DFS save how we get there to emit a nice set of notes. + SmallVector<const FieldDecl *, 4> History; + History.push_back(nullptr); + + do { + const ValueDecl *Next = StackForRecursion.pop_back_val(); + if (!Next) { + assert(!History.empty()); + // Found a marker, we have gone up a level. + History.pop_back(); + continue; + } + QualType NextTy = Next->getType(); + + if (!Visited.insert(NextTy).second) + continue; + + auto EmitHistory = [&]() { + // The first element is always nullptr. + for (uint64_t Index = 1; Index < History.size(); ++Index) { + SYCLDiagIfDeviceCode(History[Index]->getLocation(), + diag::note_within_field_of_type) + << History[Index]->getType(); + } + }; + + if (Check(NextTy, Next)) { + if (NeedToEmitNotes) + EmitHistory(); + NeedToEmitNotes = false; + } + + // In case pointer/array/reference type is met get pointee type, then + // proceed with that type. + while (NextTy->isAnyPointerType() || NextTy->isArrayType() || + NextTy->isReferenceType()) { + if (NextTy->isArrayType()) + NextTy = QualType{NextTy->getArrayElementTypeNoTypeQual(), 0}; + else + NextTy = NextTy->getPointeeType(); + if (Check(NextTy, Next)) { + if (NeedToEmitNotes) + EmitHistory(); + NeedToEmitNotes = false; + } + } + + if (const auto *RecDecl = NextTy->getAsRecordDecl()) { + if (auto *NextFD = dyn_cast<FieldDecl>(Next)) + History.push_back(NextFD); + // When nullptr is discovered, this means we've gone back up a level, so + // the history should be cleaned. + StackForRecursion.push_back(nullptr); + llvm::copy(RecDecl->fields(), std::back_inserter(StackForRecursion)); + } + } while (!StackForRecursion.empty()); +} diff --git contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp index 1d90759f2406..746eb82a5bdc 100644 --- contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp @@ -410,9 +410,13 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef<Stmt *> Elts, bool isStmtExpr) { const unsigned NumElts = Elts.size(); - // If we're in C89 mode, check that we don't have any decls after stmts. If - // so, emit an extension diagnostic. - if (!getLangOpts().C99 && !getLangOpts().CPlusPlus) { + // If we're in C mode, check that we don't have any decls after stmts. If + // so, emit an extension diagnostic in C89 and potentially a warning in later + // versions. + const unsigned MixedDeclsCodeID = getLangOpts().C99 + ? diag::warn_mixed_decls_code + : diag::ext_mixed_decls_code; + if (!getLangOpts().CPlusPlus && !Diags.isIgnored(MixedDeclsCodeID, L)) { // Note that __extension__ can be around a decl. unsigned i = 0; // Skip over all declarations. @@ -425,7 +429,7 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, if (i != NumElts) { Decl *D = *cast<DeclStmt>(Elts[i])->decl_begin(); - Diag(D->getLocation(), diag::ext_mixed_decls_code); + Diag(D->getLocation(), MixedDeclsCodeID); } } @@ -869,12 +873,7 @@ StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc, Stmt *thenStmt, SourceLocation ElseLoc, Stmt *elseStmt) { if (Cond.isInvalid()) - Cond = ConditionResult( - *this, nullptr, - MakeFullExpr(new (Context) OpaqueValueExpr(SourceLocation(), - Context.BoolTy, VK_PRValue), - IfLoc), - false); + return StmtError(); bool ConstevalOrNegatedConsteval = StatementKind == IfStatementKind::ConstevalNonNegated || @@ -2468,6 +2467,7 @@ StmtResult Sema::ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, Stmt *First, SourceLocation ColonLoc, Expr *Range, SourceLocation RParenLoc, BuildForRangeKind Kind) { + // FIXME: recover in order to allow the body to be parsed. if (!First) return StmtError(); @@ -3878,7 +3878,8 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, RetValExp, nullptr, /*RecoverUncorrectedTypos=*/true); if (RetVal.isInvalid()) return StmtError(); - StmtResult R = BuildReturnStmt(ReturnLoc, RetVal.get()); + StmtResult R = + BuildReturnStmt(ReturnLoc, RetVal.get(), /*AllowRecovery=*/true); if (R.isInvalid() || ExprEvalContexts.back().isDiscardedStatementContext()) return R; @@ -3908,7 +3909,8 @@ static bool CheckSimplerImplicitMovesMSVCWorkaround(const Sema &S, return false; } -StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { +StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, + bool AllowRecovery) { // Check for unexpanded parameter packs. if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp)) return StmtError(); @@ -3985,11 +3987,25 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { // If we've already decided this function is invalid, e.g. because // we saw a `return` whose expression had an error, don't keep // trying to deduce its return type. - if (FD->isInvalidDecl()) - return StmtError(); - if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) { + // (Some return values may be needlessly wrapped in RecoveryExpr). + if (FD->isInvalidDecl() || + DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) { FD->setInvalidDecl(); - return StmtError(); + if (!AllowRecovery) + return StmtError(); + // The deduction failure is diagnosed and marked, try to recover. + if (RetValExp) { + // Wrap return value with a recovery expression of the previous type. + // If no deduction yet, use DependentTy. + auto Recovery = CreateRecoveryExpr( + RetValExp->getBeginLoc(), RetValExp->getEndLoc(), RetValExp, + AT->isDeduced() ? FnRetType : QualType()); + if (Recovery.isInvalid()) + return StmtError(); + RetValExp = Recovery.get(); + } else { + // Nothing to do: a ReturnStmt with no value is fine recovery. + } } else { FnRetType = FD->getReturnType(); } @@ -4002,7 +4018,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { ReturnStmt *Result = nullptr; if (FnRetType->isVoidType()) { if (RetValExp) { - if (isa<InitListExpr>(RetValExp)) { + if (auto *ILE = dyn_cast<InitListExpr>(RetValExp)) { // We simply never allow init lists as the return value of void // functions. This is compatible because this was never allowed before, // so there's no legacy code to deal with. @@ -4018,8 +4034,12 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { Diag(ReturnLoc, diag::err_return_init_list) << CurDecl << FunctionKind << RetValExp->getSourceRange(); - // Drop the expression. - RetValExp = nullptr; + // Preserve the initializers in the AST. + RetValExp = AllowRecovery + ? CreateRecoveryExpr(ILE->getLBraceLoc(), + ILE->getRBraceLoc(), ILE->inits()) + .get() + : nullptr; } else if (!RetValExp->isTypeDependent()) { // C99 6.8.6.4p1 (ext_ since GCC warns) unsigned D = diag::ext_return_has_expr; @@ -4116,6 +4136,9 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { InitializedEntity::InitializeResult(ReturnLoc, RetType); ExprResult Res = PerformMoveOrCopyInitialization( Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves); + if (Res.isInvalid() && AllowRecovery) + Res = CreateRecoveryExpr(RetValExp->getBeginLoc(), + RetValExp->getEndLoc(), RetValExp, RetType); if (Res.isInvalid()) { // FIXME: Clean up temporaries here anyway? return StmtError(); diff --git contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp index 2482f6d404ea..64a0b45feb98 100644 --- contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp @@ -2063,7 +2063,7 @@ DeclResult Sema::CheckClassTemplate( } if (PrevClassTemplate) - CheckRedeclarationModuleOwnership(NewTemplate, PrevClassTemplate); + CheckRedeclarationInModule(NewTemplate, PrevClassTemplate); if (Invalid) { NewTemplate->setInvalidDecl(); @@ -3672,7 +3672,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, SmallVector<TemplateArgument, 4> Converted; if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs, false, Converted, - /*UpdateArgsWithConversion=*/true)) + /*UpdateArgsWithConversions=*/true)) return QualType(); QualType CanonType; @@ -4318,7 +4318,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization( SmallVector<TemplateArgument, 4> Converted; if (CheckTemplateArgumentList(VarTemplate, TemplateNameLoc, TemplateArgs, false, Converted, - /*UpdateArgsWithConversion=*/true)) + /*UpdateArgsWithConversions=*/true)) return true; // Find the variable template (partial) specialization declaration that @@ -4489,7 +4489,7 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc, if (CheckTemplateArgumentList( Template, TemplateNameLoc, const_cast<TemplateArgumentListInfo &>(TemplateArgs), false, - Converted, /*UpdateArgsWithConversion=*/true)) + Converted, /*UpdateArgsWithConversions=*/true)) return true; // Produce a placeholder value if the specialization is dependent. @@ -4677,7 +4677,7 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, if (CheckTemplateArgumentList(NamedConcept, ConceptNameInfo.getLoc(), const_cast<TemplateArgumentListInfo&>(*TemplateArgs), /*PartialTemplateArgs=*/false, Converted, - /*UpdateArgsWithConversion=*/false)) + /*UpdateArgsWithConversions=*/false)) return ExprError(); ConstraintSatisfaction Satisfaction; @@ -8343,7 +8343,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( SmallVector<TemplateArgument, 4> Converted; if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, TemplateArgs, false, Converted, - /*UpdateArgsWithConversion=*/true)) + /*UpdateArgsWithConversions=*/true)) return true; // Find the class template (partial) specialization declaration that @@ -9595,7 +9595,7 @@ DeclResult Sema::ActOnExplicitInstantiation( SmallVector<TemplateArgument, 4> Converted; if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, TemplateArgs, false, Converted, - /*UpdateArgsWithConversion=*/true)) + /*UpdateArgsWithConversions=*/true)) return true; // Find the class template specialization declaration that diff --git contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp index e9636d2b942e..22dd395d9943 100644 --- contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4452,7 +4452,7 @@ namespace { public: SubstituteDeducedTypeTransform(Sema &SemaRef, DependentAuto DA) - : TreeTransform<SubstituteDeducedTypeTransform>(SemaRef), Replacement(), + : TreeTransform<SubstituteDeducedTypeTransform>(SemaRef), ReplacementIsPack(DA.IsPack), UseTypeSugar(true) {} SubstituteDeducedTypeTransform(Sema &SemaRef, QualType Replacement, diff --git contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp index 7d4c000e7e90..7c6bb4c8a5f8 100644 --- contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2790,11 +2790,10 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, CurrentInstantiationScope = I->Scope; // Allow 'this' within late-parsed attributes. - NamedDecl *ND = dyn_cast<NamedDecl>(I->NewDecl); - CXXRecordDecl *ThisContext = - dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()); + auto *ND = cast<NamedDecl>(I->NewDecl); + auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()); CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(), - ND && ND->isCXXInstanceMember()); + ND->isCXXInstanceMember()); Attr *NewAttr = instantiateTemplateAttribute(I->TmplAttr, Context, *this, TemplateArgs); diff --git contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 27ac2cd08f2a..1da0dfec3f23 100644 --- contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3637,7 +3637,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( InstTemplateArgs, false, Converted, - /*UpdateArgsWithConversion=*/true)) + /*UpdateArgsWithConversions=*/true)) return nullptr; // Figure out where to insert this class template explicit specialization @@ -3759,7 +3759,7 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( SmallVector<TemplateArgument, 4> Converted; if (SemaRef.CheckTemplateArgumentList(InstVarTemplate, D->getLocation(), VarTemplateArgsInfo, false, Converted, - /*UpdateArgsWithConversion=*/true)) + /*UpdateArgsWithConversions=*/true)) return nullptr; // Check whether we've already seen a declaration of this specialization. diff --git contrib/llvm-project/clang/lib/Sema/SemaType.cpp contrib/llvm-project/clang/lib/Sema/SemaType.cpp index 7a038301a249..959f4903b030 100644 --- contrib/llvm-project/clang/lib/Sema/SemaType.cpp +++ contrib/llvm-project/clang/lib/Sema/SemaType.cpp @@ -22,6 +22,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeLocVisitor.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/DeclSpec.h" @@ -1495,8 +1496,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { } case DeclSpec::TST_int128: if (!S.Context.getTargetInfo().hasInt128Type() && - !S.getLangOpts().SYCLIsDevice && - !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice)) + !(S.getLangOpts().SYCLIsDevice || S.getLangOpts().CUDAIsDevice || + (S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice))) S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) << "__int128"; if (DS.getTypeSpecSign() == TypeSpecifierSign::Unsigned) @@ -2515,7 +2516,7 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, Diag(ArraySize->getBeginLoc(), isSFINAEContext() ? diag::err_typecheck_zero_array_size : diag::ext_typecheck_zero_array_size) - << ArraySize->getSourceRange(); + << 0 << ArraySize->getSourceRange(); } // Is the array too large? @@ -5973,6 +5974,11 @@ namespace { Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); TL.setUnderlyingTInfo(TInfo); } + void VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { + assert(DS.getTypeSpecType() == DeclSpec::TST_decltype); + TL.setDecltypeLoc(DS.getTypeSpecTypeLoc()); + TL.setRParenLoc(DS.getTypeofParensRange().getEnd()); + } void VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { // FIXME: This holds only because we only have one unary transform. assert(DS.getTypeSpecType() == DeclSpec::TST_underlyingType); @@ -6036,6 +6042,8 @@ namespace { DS.getTypeSpecType() == TST_auto_type || DS.getTypeSpecType() == TST_unspecified); TL.setNameLoc(DS.getTypeSpecTypeLoc()); + if (DS.getTypeSpecType() == TST_decltype_auto) + TL.setRParenLoc(DS.getTypeofParensRange().getEnd()); if (!DS.isConstrainedAuto()) return; TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId(); diff --git contrib/llvm-project/clang/lib/Sema/TreeTransform.h contrib/llvm-project/clang/lib/Sema/TreeTransform.h index 298a3f7a83d8..e43b3ca968eb 100644 --- contrib/llvm-project/clang/lib/Sema/TreeTransform.h +++ contrib/llvm-project/clang/lib/Sema/TreeTransform.h @@ -4076,7 +4076,8 @@ Sema::ConditionResult TreeTransform<Derived>::TransformCondition( if (CondExpr.isInvalid()) return Sema::ConditionError(); - return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind); + return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind, + /*MissingOK=*/true); } return Sema::ConditionResult(); @@ -6228,15 +6229,15 @@ QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB, QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || E.get() != T->getUnderlyingExpr()) { - Result = getDerived().RebuildDecltypeType(E.get(), TL.getNameLoc()); + Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc()); if (Result.isNull()) return QualType(); } else E.get(); DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - + NewTL.setDecltypeLoc(TL.getDecltypeLoc()); + NewTL.setRParenLoc(TL.getRParenLoc()); return Result; } @@ -6634,6 +6635,7 @@ QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB, NewTL.setFoundDecl(TL.getFoundDecl()); NewTL.setLAngleLoc(TL.getLAngleLoc()); NewTL.setRAngleLoc(TL.getRAngleLoc()); + NewTL.setRParenLoc(TL.getRParenLoc()); for (unsigned I = 0; I < NewTL.getNumArgs(); ++I) NewTL.setArgLocInfo(I, NewTemplateArgs.arguments()[I].getLocInfo()); diff --git contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp index f93e0d2ed1c4..d806fb9e1949 100644 --- contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp +++ contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp @@ -142,7 +142,6 @@ using namespace clang; using namespace clang::serialization; using namespace clang::serialization::reader; using llvm::BitstreamCursor; -using llvm::RoundingMode; //===----------------------------------------------------------------------===// // ChainedASTReaderListener implementation @@ -1888,10 +1887,6 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, HFI.isPragmaOnce |= (Flags >> 4) & 0x01; HFI.DirInfo = (Flags >> 1) & 0x07; HFI.IndexHeaderMapHeader = Flags & 0x01; - // FIXME: Find a better way to handle this. Maybe just store a - // "has been included" flag? - HFI.NumIncludes = std::max(endian::readNext<uint16_t, little, unaligned>(d), - HFI.NumIncludes); HFI.ControllingMacroID = Reader.getGlobalIdentifierID( M, endian::readNext<uint32_t, little, unaligned>(d)); if (unsigned FrameworkOffset = @@ -2963,6 +2958,22 @@ ASTReader::ReadControlBlock(ModuleFile &F, } } +void ASTReader::readIncludedFiles(ModuleFile &F, StringRef Blob, + Preprocessor &PP) { + using namespace llvm::support; + + const unsigned char *D = (const unsigned char *)Blob.data(); + unsigned FileCount = endian::readNext<uint32_t, little, unaligned>(D); + + for (unsigned I = 0; I < FileCount; ++I) { + size_t ID = endian::readNext<uint32_t, little, unaligned>(D); + InputFileInfo IFI = readInputFileInfo(F, ID); + if (llvm::ErrorOr<const FileEntry *> File = + PP.getFileManager().getFile(IFI.Filename)) + PP.getIncludedFiles().insert(*File); + } +} + llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { BitstreamCursor &Stream = F.Stream; @@ -3701,6 +3712,10 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; } + case PP_INCLUDED_FILES: + readIncludedFiles(F, Blob, PP); + break; + case LATE_PARSED_TEMPLATE: LateParsedTemplates.emplace_back( std::piecewise_construct, std::forward_as_tuple(&F), @@ -4762,11 +4777,11 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( break; unsigned Count = Record[0]; const char *Byte = Blob.data(); - F->SearchPathUsage = llvm::BitVector(Count, 0); + F->SearchPathUsage = llvm::BitVector(Count, false); for (unsigned I = 0; I < Count; ++Byte) for (unsigned Bit = 0; Bit < 8 && I < Count; ++Bit, ++I) if (*Byte & (1 << Bit)) - F->SearchPathUsage[I] = 1; + F->SearchPathUsage[I] = true; break; } } @@ -6629,7 +6644,8 @@ void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { } void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { - TL.setNameLoc(readSourceLocation()); + TL.setDecltypeLoc(readSourceLocation()); + TL.setRParenLoc(readSourceLocation()); } void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { @@ -6652,6 +6668,8 @@ void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) { TL.setArgLocInfo(i, Reader.readTemplateArgumentLocInfo( TL.getTypePtr()->getArg(i).getKind())); } + if (Reader.readBool()) + TL.setRParenLoc(readSourceLocation()); } void TypeLocReader::VisitDeducedTemplateSpecializationTypeLoc( diff --git contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp index 2144befcdb14..1ab26e58a404 100644 --- contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp +++ contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2945,391 +2945,6 @@ uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint64_t LocalOffset) { return LocalOffset + M.GlobalBitOffset; } -static bool isSameTemplateParameterList(const ASTContext &C, - const TemplateParameterList *X, - const TemplateParameterList *Y); -static bool isSameEntity(NamedDecl *X, NamedDecl *Y); - -/// Determine whether two template parameters are similar enough -/// that they may be used in declarations of the same template. -static bool isSameTemplateParameter(const NamedDecl *X, - const NamedDecl *Y) { - if (X->getKind() != Y->getKind()) - return false; - - if (const auto *TX = dyn_cast<TemplateTypeParmDecl>(X)) { - const auto *TY = cast<TemplateTypeParmDecl>(Y); - if (TX->isParameterPack() != TY->isParameterPack()) - return false; - if (TX->hasTypeConstraint() != TY->hasTypeConstraint()) - return false; - const TypeConstraint *TXTC = TX->getTypeConstraint(); - const TypeConstraint *TYTC = TY->getTypeConstraint(); - if (!TXTC != !TYTC) - return false; - if (TXTC && TYTC) { - auto *NCX = TXTC->getNamedConcept(); - auto *NCY = TYTC->getNamedConcept(); - if (!NCX || !NCY || !isSameEntity(NCX, NCY)) - return false; - if (TXTC->hasExplicitTemplateArgs() != TYTC->hasExplicitTemplateArgs()) - return false; - if (TXTC->hasExplicitTemplateArgs()) { - const auto *TXTCArgs = TXTC->getTemplateArgsAsWritten(); - const auto *TYTCArgs = TYTC->getTemplateArgsAsWritten(); - if (TXTCArgs->NumTemplateArgs != TYTCArgs->NumTemplateArgs) - return false; - llvm::FoldingSetNodeID XID, YID; - for (const auto &ArgLoc : TXTCArgs->arguments()) - ArgLoc.getArgument().Profile(XID, X->getASTContext()); - for (const auto &ArgLoc : TYTCArgs->arguments()) - ArgLoc.getArgument().Profile(YID, Y->getASTContext()); - if (XID != YID) - return false; - } - } - return true; - } - - if (const auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) { - const auto *TY = cast<NonTypeTemplateParmDecl>(Y); - return TX->isParameterPack() == TY->isParameterPack() && - TX->getASTContext().hasSameType(TX->getType(), TY->getType()); - } - - const auto *TX = cast<TemplateTemplateParmDecl>(X); - const auto *TY = cast<TemplateTemplateParmDecl>(Y); - return TX->isParameterPack() == TY->isParameterPack() && - isSameTemplateParameterList(TX->getASTContext(), - TX->getTemplateParameters(), - TY->getTemplateParameters()); -} - -static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) { - if (auto *NS = X->getAsNamespace()) - return NS; - if (auto *NAS = X->getAsNamespaceAlias()) - return NAS->getNamespace(); - return nullptr; -} - -static bool isSameQualifier(const NestedNameSpecifier *X, - const NestedNameSpecifier *Y) { - if (auto *NSX = getNamespace(X)) { - auto *NSY = getNamespace(Y); - if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl()) - return false; - } else if (X->getKind() != Y->getKind()) - return false; - - // FIXME: For namespaces and types, we're permitted to check that the entity - // is named via the same tokens. We should probably do so. - switch (X->getKind()) { - case NestedNameSpecifier::Identifier: - if (X->getAsIdentifier() != Y->getAsIdentifier()) - return false; - break; - case NestedNameSpecifier::Namespace: - case NestedNameSpecifier::NamespaceAlias: - // We've already checked that we named the same namespace. - break; - case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: - if (X->getAsType()->getCanonicalTypeInternal() != - Y->getAsType()->getCanonicalTypeInternal()) - return false; - break; - case NestedNameSpecifier::Global: - case NestedNameSpecifier::Super: - return true; - } - - // Recurse into earlier portion of NNS, if any. - auto *PX = X->getPrefix(); - auto *PY = Y->getPrefix(); - if (PX && PY) - return isSameQualifier(PX, PY); - return !PX && !PY; -} - -/// Determine whether two template parameter lists are similar enough -/// that they may be used in declarations of the same template. -static bool isSameTemplateParameterList(const ASTContext &C, - const TemplateParameterList *X, - const TemplateParameterList *Y) { - if (X->size() != Y->size()) - return false; - - for (unsigned I = 0, N = X->size(); I != N; ++I) - if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I))) - return false; - - const Expr *XRC = X->getRequiresClause(); - const Expr *YRC = Y->getRequiresClause(); - if (!XRC != !YRC) - return false; - if (XRC) { - llvm::FoldingSetNodeID XRCID, YRCID; - XRC->Profile(XRCID, C, /*Canonical=*/true); - YRC->Profile(YRCID, C, /*Canonical=*/true); - if (XRCID != YRCID) - return false; - } - - return true; -} - -/// Determine whether the attributes we can overload on are identical for A and -/// B. Will ignore any overloadable attrs represented in the type of A and B. -static bool hasSameOverloadableAttrs(const FunctionDecl *A, - const FunctionDecl *B) { - // Note that pass_object_size attributes are represented in the function's - // ExtParameterInfo, so we don't need to check them here. - - llvm::FoldingSetNodeID Cand1ID, Cand2ID; - auto AEnableIfAttrs = A->specific_attrs<EnableIfAttr>(); - auto BEnableIfAttrs = B->specific_attrs<EnableIfAttr>(); - - for (auto Pair : zip_longest(AEnableIfAttrs, BEnableIfAttrs)) { - Optional<EnableIfAttr *> Cand1A = std::get<0>(Pair); - Optional<EnableIfAttr *> Cand2A = std::get<1>(Pair); - - // Return false if the number of enable_if attributes is different. - if (!Cand1A || !Cand2A) - return false; - - Cand1ID.clear(); - Cand2ID.clear(); - - (*Cand1A)->getCond()->Profile(Cand1ID, A->getASTContext(), true); - (*Cand2A)->getCond()->Profile(Cand2ID, B->getASTContext(), true); - - // Return false if any of the enable_if expressions of A and B are - // different. - if (Cand1ID != Cand2ID) - return false; - } - return true; -} - -/// Determine whether the two declarations refer to the same entity. -static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { - if (X == Y) - return true; - - if (X->getDeclName() != Y->getDeclName()) - return false; - - // Must be in the same context. - // - // Note that we can't use DeclContext::Equals here, because the DeclContexts - // could be two different declarations of the same function. (We will fix the - // semantic DC to refer to the primary definition after merging.) - if (!declaresSameEntity(cast<Decl>(X->getDeclContext()->getRedeclContext()), - cast<Decl>(Y->getDeclContext()->getRedeclContext()))) - return false; - - // Two typedefs refer to the same entity if they have the same underlying - // type. - if (const auto *TypedefX = dyn_cast<TypedefNameDecl>(X)) - if (const auto *TypedefY = dyn_cast<TypedefNameDecl>(Y)) - return X->getASTContext().hasSameType(TypedefX->getUnderlyingType(), - TypedefY->getUnderlyingType()); - - // Must have the same kind. - if (X->getKind() != Y->getKind()) - return false; - - // Objective-C classes and protocols with the same name always match. - if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X)) - return true; - - if (isa<ClassTemplateSpecializationDecl>(X)) { - // No need to handle these here: we merge them when adding them to the - // template. - return false; - } - - // Compatible tags match. - if (const auto *TagX = dyn_cast<TagDecl>(X)) { - const auto *TagY = cast<TagDecl>(Y); - return (TagX->getTagKind() == TagY->getTagKind()) || - ((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class || - TagX->getTagKind() == TTK_Interface) && - (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class || - TagY->getTagKind() == TTK_Interface)); - } - - // Functions with the same type and linkage match. - // FIXME: This needs to cope with merging of prototyped/non-prototyped - // functions, etc. - if (const auto *FuncX = dyn_cast<FunctionDecl>(X)) { - const auto *FuncY = cast<FunctionDecl>(Y); - if (const auto *CtorX = dyn_cast<CXXConstructorDecl>(X)) { - const auto *CtorY = cast<CXXConstructorDecl>(Y); - if (CtorX->getInheritedConstructor() && - !isSameEntity(CtorX->getInheritedConstructor().getConstructor(), - CtorY->getInheritedConstructor().getConstructor())) - return false; - } - - if (FuncX->isMultiVersion() != FuncY->isMultiVersion()) - return false; - - // Multiversioned functions with different feature strings are represented - // as separate declarations. - if (FuncX->isMultiVersion()) { - const auto *TAX = FuncX->getAttr<TargetAttr>(); - const auto *TAY = FuncY->getAttr<TargetAttr>(); - assert(TAX && TAY && "Multiversion Function without target attribute"); - - if (TAX->getFeaturesStr() != TAY->getFeaturesStr()) - return false; - } - - ASTContext &C = FuncX->getASTContext(); - - const Expr *XRC = FuncX->getTrailingRequiresClause(); - const Expr *YRC = FuncY->getTrailingRequiresClause(); - if (!XRC != !YRC) - return false; - if (XRC) { - llvm::FoldingSetNodeID XRCID, YRCID; - XRC->Profile(XRCID, C, /*Canonical=*/true); - YRC->Profile(YRCID, C, /*Canonical=*/true); - if (XRCID != YRCID) - return false; - } - - auto GetTypeAsWritten = [](const FunctionDecl *FD) { - // Map to the first declaration that we've already merged into this one. - // The TSI of redeclarations might not match (due to calling conventions - // being inherited onto the type but not the TSI), but the TSI type of - // the first declaration of the function should match across modules. - FD = FD->getCanonicalDecl(); - return FD->getTypeSourceInfo() ? FD->getTypeSourceInfo()->getType() - : FD->getType(); - }; - QualType XT = GetTypeAsWritten(FuncX), YT = GetTypeAsWritten(FuncY); - if (!C.hasSameType(XT, YT)) { - // We can get functions with different types on the redecl chain in C++17 - // if they have differing exception specifications and at least one of - // the excpetion specs is unresolved. - auto *XFPT = XT->getAs<FunctionProtoType>(); - auto *YFPT = YT->getAs<FunctionProtoType>(); - if (C.getLangOpts().CPlusPlus17 && XFPT && YFPT && - (isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) || - isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) && - C.hasSameFunctionTypeIgnoringExceptionSpec(XT, YT)) - return true; - return false; - } - - return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() && - hasSameOverloadableAttrs(FuncX, FuncY); - } - - // Variables with the same type and linkage match. - if (const auto *VarX = dyn_cast<VarDecl>(X)) { - const auto *VarY = cast<VarDecl>(Y); - if (VarX->getLinkageInternal() == VarY->getLinkageInternal()) { - ASTContext &C = VarX->getASTContext(); - if (C.hasSameType(VarX->getType(), VarY->getType())) - return true; - - // We can get decls with different types on the redecl chain. Eg. - // template <typename T> struct S { static T Var[]; }; // #1 - // template <typename T> T S<T>::Var[sizeof(T)]; // #2 - // Only? happens when completing an incomplete array type. In this case - // when comparing #1 and #2 we should go through their element type. - const ArrayType *VarXTy = C.getAsArrayType(VarX->getType()); - const ArrayType *VarYTy = C.getAsArrayType(VarY->getType()); - if (!VarXTy || !VarYTy) - return false; - if (VarXTy->isIncompleteArrayType() || VarYTy->isIncompleteArrayType()) - return C.hasSameType(VarXTy->getElementType(), VarYTy->getElementType()); - } - return false; - } - - // Namespaces with the same name and inlinedness match. - if (const auto *NamespaceX = dyn_cast<NamespaceDecl>(X)) { - const auto *NamespaceY = cast<NamespaceDecl>(Y); - return NamespaceX->isInline() == NamespaceY->isInline(); - } - - // Identical template names and kinds match if their template parameter lists - // and patterns match. - if (const auto *TemplateX = dyn_cast<TemplateDecl>(X)) { - const auto *TemplateY = cast<TemplateDecl>(Y); - return isSameEntity(TemplateX->getTemplatedDecl(), - TemplateY->getTemplatedDecl()) && - isSameTemplateParameterList(TemplateX->getASTContext(), - TemplateX->getTemplateParameters(), - TemplateY->getTemplateParameters()); - } - - // Fields with the same name and the same type match. - if (const auto *FDX = dyn_cast<FieldDecl>(X)) { - const auto *FDY = cast<FieldDecl>(Y); - // FIXME: Also check the bitwidth is odr-equivalent, if any. - return X->getASTContext().hasSameType(FDX->getType(), FDY->getType()); - } - - // Indirect fields with the same target field match. - if (const auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) { - const auto *IFDY = cast<IndirectFieldDecl>(Y); - return IFDX->getAnonField()->getCanonicalDecl() == - IFDY->getAnonField()->getCanonicalDecl(); - } - - // Enumerators with the same name match. - if (isa<EnumConstantDecl>(X)) - // FIXME: Also check the value is odr-equivalent. - return true; - - // Using shadow declarations with the same target match. - if (const auto *USX = dyn_cast<UsingShadowDecl>(X)) { - const auto *USY = cast<UsingShadowDecl>(Y); - return USX->getTargetDecl() == USY->getTargetDecl(); - } - - // Using declarations with the same qualifier match. (We already know that - // the name matches.) - if (const auto *UX = dyn_cast<UsingDecl>(X)) { - const auto *UY = cast<UsingDecl>(Y); - return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && - UX->hasTypename() == UY->hasTypename() && - UX->isAccessDeclaration() == UY->isAccessDeclaration(); - } - if (const auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) { - const auto *UY = cast<UnresolvedUsingValueDecl>(Y); - return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && - UX->isAccessDeclaration() == UY->isAccessDeclaration(); - } - if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X)) { - return isSameQualifier( - UX->getQualifier(), - cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier()); - } - - // Using-pack declarations are only created by instantiation, and match if - // they're instantiated from matching UnresolvedUsing...Decls. - if (const auto *UX = dyn_cast<UsingPackDecl>(X)) { - return declaresSameEntity( - UX->getInstantiatedFromUsingDecl(), - cast<UsingPackDecl>(Y)->getInstantiatedFromUsingDecl()); - } - - // Namespace alias definitions with the same target match. - if (const auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) { - const auto *NAY = cast<NamespaceAliasDecl>(Y); - return NAX->getNamespace()->Equals(NAY->getNamespace()); - } - - return false; -} - /// Find the context in which we should search for previous declarations when /// looking for declarations to merge. DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader, @@ -3511,12 +3126,13 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { return Result; } + ASTContext &C = Reader.getContext(); DeclContext *DC = D->getDeclContext()->getRedeclContext(); if (TypedefNameForLinkage) { auto It = Reader.ImportedTypedefNamesForLinkage.find( std::make_pair(DC, TypedefNameForLinkage)); if (It != Reader.ImportedTypedefNamesForLinkage.end()) - if (isSameEntity(It->second, D)) + if (C.isSameEntity(It->second, D)) return FindExistingResult(Reader, D, It->second, AnonymousDeclNumber, TypedefNameForLinkage); // Go on to check in other places in case an existing typedef name @@ -3528,7 +3144,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { // in its context by number. if (auto *Existing = getAnonymousDeclForMerging( Reader, D->getLexicalDeclContext(), AnonymousDeclNumber)) - if (isSameEntity(Existing, D)) + if (C.isSameEntity(Existing, D)) return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, TypedefNameForLinkage); } else if (DC->isTranslationUnit() && @@ -3560,7 +3176,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { IEnd = IdResolver.end(); I != IEnd; ++I) { if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage)) - if (isSameEntity(Existing, D)) + if (C.isSameEntity(Existing, D)) return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, TypedefNameForLinkage); } @@ -3568,7 +3184,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { DeclContext::lookup_result R = MergeDC->noload_lookup(Name); for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) { if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage)) - if (isSameEntity(Existing, D)) + if (C.isSameEntity(Existing, D)) return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, TypedefNameForLinkage); } @@ -4781,10 +4397,12 @@ void ASTDeclReader::UpdateDecl(Decl *D, case UPD_DECL_MARKED_OPENMP_DECLARETARGET: { auto MapType = Record.readEnum<OMPDeclareTargetDeclAttr::MapTypeTy>(); auto DevType = Record.readEnum<OMPDeclareTargetDeclAttr::DevTypeTy>(); + Expr *IndirectE = Record.readExpr(); + bool Indirect = Record.readBool(); unsigned Level = Record.readInt(); D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit( - Reader.getContext(), MapType, DevType, Level, readSourceRange(), - AttributeCommonInfo::AS_Pragma)); + Reader.getContext(), MapType, DevType, IndirectE, Indirect, Level, + readSourceRange(), AttributeCommonInfo::AS_Pragma)); break; } diff --git contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h index 265a77fdb215..4a4cfcce156d 100644 --- contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h +++ contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h @@ -30,7 +30,6 @@ class ASTReader; class FileEntry; struct HeaderFileInfo; class HeaderSearch; -class IdentifierTable; class ObjCMethodDecl; namespace serialization { diff --git contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp index 65a780e67510..763fc9537c04 100644 --- contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp +++ contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp @@ -427,7 +427,8 @@ void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { } void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { - Record.AddSourceLocation(TL.getNameLoc()); + Record.AddSourceLocation(TL.getDecltypeLoc()); + Record.AddSourceLocation(TL.getRParenLoc()); } void TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { @@ -451,6 +452,9 @@ void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) { Record.AddTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(), TL.getArgLocInfo(I)); } + Record.push_back(TL.isDecltypeAuto()); + if (TL.isDecltypeAuto()) + Record.AddSourceLocation(TL.getRParenLoc()); } void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc( @@ -858,6 +862,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH); RECORD(PP_CONDITIONAL_STACK); RECORD(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS); + RECORD(PP_INCLUDED_FILES); // SourceManager Block. BLOCK(SOURCE_MANAGER_BLOCK); @@ -1769,7 +1774,7 @@ namespace { std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref Data) { unsigned KeyLen = key.Filename.size() + 1 + 8 + 8; - unsigned DataLen = 1 + 2 + 4 + 4; + unsigned DataLen = 1 + 4 + 4; for (auto ModInfo : Data.KnownHeaders) if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule())) DataLen += 4; @@ -1801,7 +1806,6 @@ namespace { | (Data.HFI.DirInfo << 1) | Data.HFI.IndexHeaderMapHeader; LE.write<uint8_t>(Flags); - LE.write<uint16_t>(Data.HFI.NumIncludes); if (!Data.HFI.ControllingMacro) LE.write<uint32_t>(Data.HFI.ControllingMacroID); @@ -2250,6 +2254,29 @@ static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule, return false; } +void ASTWriter::writeIncludedFiles(raw_ostream &Out, const Preprocessor &PP) { + using namespace llvm::support; + + const Preprocessor::IncludedFilesSet &IncludedFiles = PP.getIncludedFiles(); + + std::vector<uint32_t> IncludedInputFileIDs; + IncludedInputFileIDs.reserve(IncludedFiles.size()); + + for (const FileEntry *File : IncludedFiles) { + auto InputFileIt = InputFileIDs.find(File); + if (InputFileIt == InputFileIDs.end()) + continue; + IncludedInputFileIDs.push_back(InputFileIt->second); + } + + llvm::sort(IncludedInputFileIDs); + + endian::Writer LE(Out, little); + LE.write<uint32_t>(IncludedInputFileIDs.size()); + for (uint32_t ID : IncludedInputFileIDs) + LE.write<uint32_t>(ID); +} + /// Writes the block containing the serialized form of the /// preprocessor. void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { @@ -2458,6 +2485,20 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { MacroOffsetsBase - ASTBlockStartOffset}; Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record, bytes(MacroOffsets)); } + + { + auto Abbrev = std::make_shared<BitCodeAbbrev>(); + Abbrev->Add(BitCodeAbbrevOp(PP_INCLUDED_FILES)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + unsigned IncludedFilesAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); + + SmallString<2048> Buffer; + raw_svector_ostream Out(Buffer); + writeIncludedFiles(Out, PP); + RecordData::value_type Record[] = {PP_INCLUDED_FILES}; + Stream.EmitRecordWithBlob(IncludedFilesAbbrev, Record, Buffer.data(), + Buffer.size()); + } } void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec, diff --git contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp index f4882c7be3f7..4fd217cf7a6e 100644 --- contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp +++ contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp @@ -304,23 +304,22 @@ ModuleManager::addInMemoryBuffer(StringRef FileName, InMemoryBuffers[Entry] = std::move(Buffer); } -ModuleManager::VisitState *ModuleManager::allocateVisitState() { +std::unique_ptr<ModuleManager::VisitState> ModuleManager::allocateVisitState() { // Fast path: if we have a cached state, use it. if (FirstVisitState) { - VisitState *Result = FirstVisitState; - FirstVisitState = FirstVisitState->NextState; - Result->NextState = nullptr; + auto Result = std::move(FirstVisitState); + FirstVisitState = std::move(Result->NextState); return Result; } // Allocate and return a new state. - return new VisitState(size()); + return std::make_unique<VisitState>(size()); } -void ModuleManager::returnVisitState(VisitState *State) { +void ModuleManager::returnVisitState(std::unique_ptr<VisitState> State) { assert(State->NextState == nullptr && "Visited state is in list?"); - State->NextState = FirstVisitState; - FirstVisitState = State; + State->NextState = std::move(FirstVisitState); + FirstVisitState = std::move(State); } void ModuleManager::setGlobalIndex(GlobalModuleIndex *Index) { @@ -351,8 +350,6 @@ ModuleManager::ModuleManager(FileManager &FileMgr, : FileMgr(FileMgr), ModuleCache(&ModuleCache), PCHContainerRdr(PCHContainerRdr), HeaderSearchInfo(HeaderSearchInfo) {} -ModuleManager::~ModuleManager() { delete FirstVisitState; } - void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor, llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) { // If the visitation order vector is the wrong size, recompute the order. @@ -396,11 +393,10 @@ void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor, assert(VisitOrder.size() == N && "Visitation order is wrong?"); - delete FirstVisitState; FirstVisitState = nullptr; } - VisitState *State = allocateVisitState(); + auto State = allocateVisitState(); unsigned VisitNumber = State->NextVisitNumber++; // If the caller has provided us with a hit-set that came from the global @@ -452,7 +448,7 @@ void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor, } while (true); } - returnVisitState(State); + returnVisitState(std::move(State)); } bool ModuleManager::lookupModuleFile(StringRef FileName, off_t ExpectedSize, diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp index 7cdd78b8adfb..7841fd82e370 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp @@ -302,7 +302,7 @@ class ExplodedGraphViewer : public Checker< check::EndAnalysis > { public: ExplodedGraphViewer() {} void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const { - Eng.ViewGraph(0); + Eng.ViewGraph(false); } }; diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp index 66ef781871ec..e2209e3debfd 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp @@ -22,15 +22,14 @@ #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "llvm/Support/YAMLTraits.h" -#include <algorithm> #include <limits> #include <memory> -#include <unordered_map> #include <utility> using namespace clang; @@ -38,577 +37,651 @@ using namespace ento; using namespace taint; namespace { -class GenericTaintChecker : public Checker<check::PreCall, check::PostCall> { -public: - static void *getTag() { - static int Tag; - return &Tag; + +class GenericTaintChecker; + +/// Check for CWE-134: Uncontrolled Format String. +constexpr llvm::StringLiteral MsgUncontrolledFormatString = + "Untrusted data is used as a format string " + "(CWE-134: Uncontrolled Format String)"; + +/// Check for: +/// CERT/STR02-C. "Sanitize data passed to complex subsystems" +/// CWE-78, "Failure to Sanitize Data into an OS Command" +constexpr llvm::StringLiteral MsgSanitizeSystemArgs = + "Untrusted data is passed to a system call " + "(CERT/STR02-C. Sanitize data passed to complex subsystems)"; + +/// Check if tainted data is used as a buffer size in strn.. functions, +/// and allocators. +constexpr llvm::StringLiteral MsgTaintedBufferSize = + "Untrusted data is used to specify the buffer size " + "(CERT/STR31-C. Guarantee that storage for strings has sufficient space " + "for character data and the null terminator)"; + +/// Check if tainted data is used as a custom sink's parameter. +constexpr llvm::StringLiteral MsgCustomSink = + "Untrusted data is passed to a user-defined sink"; + +using ArgIdxTy = int; +using ArgVecTy = llvm::SmallVector<ArgIdxTy, 2>; + +/// Denotes the return value. +constexpr ArgIdxTy ReturnValueIndex{-1}; + +static ArgIdxTy fromArgumentCount(unsigned Count) { + assert(Count <= + static_cast<std::size_t>(std::numeric_limits<ArgIdxTy>::max()) && + "ArgIdxTy is not large enough to represent the number of arguments."); + return Count; +} + +/// Check if the region the expression evaluates to is the standard input, +/// and thus, is tainted. +/// FIXME: Move this to Taint.cpp. +bool isStdin(SVal Val, const ASTContext &ACtx) { + // FIXME: What if Val is NonParamVarRegion? + + // The region should be symbolic, we do not know it's value. + const auto *SymReg = dyn_cast_or_null<SymbolicRegion>(Val.getAsRegion()); + if (!SymReg) + return false; + + // Get it's symbol and find the declaration region it's pointing to. + const auto *Sm = dyn_cast<SymbolRegionValue>(SymReg->getSymbol()); + if (!Sm) + return false; + const auto *DeclReg = dyn_cast<DeclRegion>(Sm->getRegion()); + if (!DeclReg) + return false; + + // This region corresponds to a declaration, find out if it's a global/extern + // variable named stdin with the proper type. + if (const auto *D = dyn_cast_or_null<VarDecl>(DeclReg->getDecl())) { + D = D->getCanonicalDecl(); + // FIXME: This should look for an exact match. + if (D->getName().contains("stdin") && D->isExternC()) { + const QualType FILETy = ACtx.getFILEType().getCanonicalType(); + const QualType Ty = D->getType().getCanonicalType(); + + if (Ty->isPointerType()) + return Ty->getPointeeType() == FILETy; + } } + return false; +} - void checkPreCall(const CallEvent &Call, CheckerContext &C) const; - void checkPostCall(const CallEvent &Call, CheckerContext &C) const; +SVal getPointeeOf(const CheckerContext &C, Loc LValue) { + const QualType ArgTy = LValue.getType(C.getASTContext()); + if (!ArgTy->isPointerType() || !ArgTy->getPointeeType()->isVoidType()) + return C.getState()->getSVal(LValue); - void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, - const char *Sep) const override; + // Do not dereference void pointers. Treat them as byte pointers instead. + // FIXME: we might want to consider more than just the first byte. + return C.getState()->getSVal(LValue, C.getASTContext().CharTy); +} + +/// Given a pointer/reference argument, return the value it refers to. +Optional<SVal> getPointeeOf(const CheckerContext &C, SVal Arg) { + if (auto LValue = Arg.getAs<Loc>()) + return getPointeeOf(C, *LValue); + return None; +} - using ArgVector = SmallVector<unsigned, 2>; - using SignedArgVector = SmallVector<int, 2>; +/// Given a pointer, return the SVal of its pointee or if it is tainted, +/// otherwise return the pointer's SVal if tainted. +/// Also considers stdin as a taint source. +Optional<SVal> getTaintedPointeeOrPointer(const CheckerContext &C, SVal Arg) { + const ProgramStateRef State = C.getState(); - enum class VariadicType { None, Src, Dst }; + if (auto Pointee = getPointeeOf(C, Arg)) + if (isTainted(State, *Pointee)) // FIXME: isTainted(...) ? Pointee : None; + return Pointee; - /// Used to parse the configuration file. - struct TaintConfiguration { - using NameScopeArgs = std::tuple<std::string, std::string, ArgVector>; - - struct Propagation { - std::string Name; - std::string Scope; - ArgVector SrcArgs; - SignedArgVector DstArgs; - VariadicType VarType; - unsigned VarIndex; - }; - - std::vector<Propagation> Propagations; - std::vector<NameScopeArgs> Filters; - std::vector<NameScopeArgs> Sinks; - - TaintConfiguration() = default; - TaintConfiguration(const TaintConfiguration &) = default; - TaintConfiguration(TaintConfiguration &&) = default; - TaintConfiguration &operator=(const TaintConfiguration &) = default; - TaintConfiguration &operator=(TaintConfiguration &&) = default; - }; + if (isTainted(State, Arg)) + return Arg; + + // FIXME: This should be done by the isTainted() API. + if (isStdin(Arg, C.getASTContext())) + return Arg; + + return None; +} - /// Convert SignedArgVector to ArgVector. - ArgVector convertToArgVector(CheckerManager &Mgr, const std::string &Option, - const SignedArgVector &Args); +bool isTaintedOrPointsToTainted(const Expr *E, const ProgramStateRef &State, + CheckerContext &C) { + return getTaintedPointeeOrPointer(C, C.getSVal(E)).hasValue(); +} - /// Parse the config. - void parseConfiguration(CheckerManager &Mgr, const std::string &Option, - TaintConfiguration &&Config); +/// ArgSet is used to describe arguments relevant for taint detection or +/// taint application. A discrete set of argument indexes and a variadic +/// argument list signified by a starting index are supported. +class ArgSet { +public: + ArgSet() = default; + ArgSet(ArgVecTy &&DiscreteArgs, Optional<ArgIdxTy> VariadicIndex = None) + : DiscreteArgs(std::move(DiscreteArgs)), + VariadicIndex(std::move(VariadicIndex)) {} - static const unsigned InvalidArgIndex{std::numeric_limits<unsigned>::max()}; - /// Denotes the return vale. - static const unsigned ReturnValueIndex{std::numeric_limits<unsigned>::max() - - 1}; + bool contains(ArgIdxTy ArgIdx) const { + if (llvm::is_contained(DiscreteArgs, ArgIdx)) + return true; -private: - mutable std::unique_ptr<BugType> BT; - void initBugType() const { - if (!BT) - BT = std::make_unique<BugType>(this, "Use of Untrusted Data", - "Untrusted Data"); + return VariadicIndex && ArgIdx >= *VariadicIndex; } - struct FunctionData { - FunctionData() = delete; - FunctionData(const FunctionDecl *FDecl, StringRef Name, - std::string FullName) - : FDecl(FDecl), Name(Name), FullName(std::move(FullName)) {} - FunctionData(const FunctionData &) = default; - FunctionData(FunctionData &&) = default; - FunctionData &operator=(const FunctionData &) = delete; - FunctionData &operator=(FunctionData &&) = delete; - - static Optional<FunctionData> create(const CallEvent &Call, - const CheckerContext &C) { - if (!Call.getDecl()) - return None; - - const FunctionDecl *FDecl = Call.getDecl()->getAsFunction(); - if (!FDecl || (FDecl->getKind() != Decl::Function && - FDecl->getKind() != Decl::CXXMethod)) - return None; - - StringRef Name = C.getCalleeName(FDecl); - std::string FullName = FDecl->getQualifiedNameAsString(); - if (Name.empty() || FullName.empty()) - return None; - - return FunctionData{FDecl, Name, std::move(FullName)}; - } + bool isEmpty() const { return DiscreteArgs.empty() && !VariadicIndex; } - bool isInScope(StringRef Scope) const { - return StringRef(FullName).startswith(Scope); + ArgVecTy ArgsUpTo(ArgIdxTy LastArgIdx) const { + ArgVecTy Args; + for (ArgIdxTy I = ReturnValueIndex; I <= LastArgIdx; ++I) { + if (contains(I)) + Args.push_back(I); } + return Args; + } - const FunctionDecl *const FDecl; - const StringRef Name; - const std::string FullName; - }; +private: + ArgVecTy DiscreteArgs; + Optional<ArgIdxTy> VariadicIndex; +}; - /// Catch taint related bugs. Check if tainted data is passed to a - /// system call etc. Returns true on matching. - bool checkPre(const CallEvent &Call, const FunctionData &FData, - CheckerContext &C) const; +/// A struct used to specify taint propagation rules for a function. +/// +/// If any of the possible taint source arguments is tainted, all of the +/// destination arguments should also be tainted. If ReturnValueIndex is added +/// to the dst list, the return value will be tainted. +class GenericTaintRule { + /// Arguments which are taints sinks and should be checked, and a report + /// should be emitted if taint reaches these. + ArgSet SinkArgs; + /// Arguments which should be sanitized on function return. + ArgSet FilterArgs; + /// Arguments which can participate in taint propagationa. If any of the + /// arguments in PropSrcArgs is tainted, all arguments in PropDstArgs should + /// be tainted. + ArgSet PropSrcArgs; + ArgSet PropDstArgs; + + /// A message that explains why the call is sensitive to taint. + Optional<StringRef> SinkMsg; + + GenericTaintRule() = default; + + GenericTaintRule(ArgSet &&Sink, ArgSet &&Filter, ArgSet &&Src, ArgSet &&Dst, + Optional<StringRef> SinkMsg = None) + : SinkArgs(std::move(Sink)), FilterArgs(std::move(Filter)), + PropSrcArgs(std::move(Src)), PropDstArgs(std::move(Dst)), + SinkMsg(SinkMsg) {} - /// Add taint sources on a pre-visit. Returns true on matching. - bool addSourcesPre(const CallEvent &Call, const FunctionData &FData, - CheckerContext &C) const; +public: + /// Make a rule that reports a warning if taint reaches any of \p FilterArgs + /// arguments. + static GenericTaintRule Sink(ArgSet &&SinkArgs, + Optional<StringRef> Msg = None) { + return {std::move(SinkArgs), {}, {}, {}, Msg}; + } - /// Mark filter's arguments not tainted on a pre-visit. Returns true on - /// matching. - bool addFiltersPre(const CallEvent &Call, const FunctionData &FData, - CheckerContext &C) const; + /// Make a rule that sanitizes all FilterArgs arguments. + static GenericTaintRule Filter(ArgSet &&FilterArgs) { + return {{}, std::move(FilterArgs), {}, {}}; + } - /// Propagate taint generated at pre-visit. Returns true on matching. - static bool propagateFromPre(const CallEvent &Call, CheckerContext &C); + /// Make a rule that unconditionally taints all Args. + /// If Func is provided, it must also return true for taint to propagate. + static GenericTaintRule Source(ArgSet &&SourceArgs) { + return {{}, {}, {}, std::move(SourceArgs)}; + } - /// Check if the region the expression evaluates to is the standard input, - /// and thus, is tainted. - static bool isStdin(const Expr *E, CheckerContext &C); + /// Make a rule that taints all PropDstArgs if any of PropSrcArgs is tainted. + static GenericTaintRule Prop(ArgSet &&SrcArgs, ArgSet &&DstArgs) { + return {{}, {}, std::move(SrcArgs), std::move(DstArgs)}; + } - /// Given a pointer argument, return the value it points to. - static Optional<SVal> getPointeeOf(CheckerContext &C, const Expr *Arg); + /// Make a rule that taints all PropDstArgs if any of PropSrcArgs is tainted. + static GenericTaintRule SinkProp(ArgSet &&SinkArgs, ArgSet &&SrcArgs, + ArgSet &&DstArgs, + Optional<StringRef> Msg = None) { + return { + std::move(SinkArgs), {}, std::move(SrcArgs), std::move(DstArgs), Msg}; + } - /// Check for CWE-134: Uncontrolled Format String. - static constexpr llvm::StringLiteral MsgUncontrolledFormatString = - "Untrusted data is used as a format string " - "(CWE-134: Uncontrolled Format String)"; - bool checkUncontrolledFormatString(const CallEvent &Call, - CheckerContext &C) const; + /// Process a function which could either be a taint source, a taint sink, a + /// taint filter or a taint propagator. + void process(const GenericTaintChecker &Checker, const CallEvent &Call, + CheckerContext &C) const; - /// Check for: - /// CERT/STR02-C. "Sanitize data passed to complex subsystems" - /// CWE-78, "Failure to Sanitize Data into an OS Command" - static constexpr llvm::StringLiteral MsgSanitizeSystemArgs = - "Untrusted data is passed to a system call " - "(CERT/STR02-C. Sanitize data passed to complex subsystems)"; - bool checkSystemCall(const CallEvent &Call, StringRef Name, - CheckerContext &C) const; - - /// Check if tainted data is used as a buffer size ins strn.. functions, - /// and allocators. - static constexpr llvm::StringLiteral MsgTaintedBufferSize = - "Untrusted data is used to specify the buffer size " - "(CERT/STR31-C. Guarantee that storage for strings has sufficient space " - "for character data and the null terminator)"; - bool checkTaintedBufferSize(const CallEvent &Call, CheckerContext &C) const; - - /// Check if tainted data is used as a custom sink's parameter. - static constexpr llvm::StringLiteral MsgCustomSink = - "Untrusted data is passed to a user-defined sink"; - bool checkCustomSinks(const CallEvent &Call, const FunctionData &FData, - CheckerContext &C) const; + /// Handles the resolution of indexes of type ArgIdxTy to Expr*-s. + static const Expr *GetArgExpr(ArgIdxTy ArgIdx, const CallEvent &Call) { + return ArgIdx == ReturnValueIndex ? Call.getOriginExpr() + : Call.getArgExpr(ArgIdx); + }; - /// Generate a report if the expression is tainted or points to tainted data. - bool generateReportIfTainted(const Expr *E, StringRef Msg, - CheckerContext &C) const; + /// Functions for custom taintedness propagation. + static bool UntrustedEnv(CheckerContext &C); +}; + +using RuleLookupTy = CallDescriptionMap<GenericTaintRule>; + +/// Used to parse the configuration file. +struct TaintConfiguration { + using NameScopeArgs = std::tuple<std::string, std::string, ArgVecTy>; + enum class VariadicType { None, Src, Dst }; + + struct Common { + std::string Name; + std::string Scope; + }; + + struct Sink : Common { + ArgVecTy SinkArgs; + }; + + struct Filter : Common { + ArgVecTy FilterArgs; + }; - struct TaintPropagationRule; - template <typename T> - using ConfigDataMap = - std::unordered_multimap<std::string, std::pair<std::string, T>>; - using NameRuleMap = ConfigDataMap<TaintPropagationRule>; - using NameArgMap = ConfigDataMap<ArgVector>; - - /// Find a function with the given name and scope. Returns the first match - /// or the end of the map. - template <typename T> - static auto findFunctionInConfig(const ConfigDataMap<T> &Map, - const FunctionData &FData); - - /// A struct used to specify taint propagation rules for a function. - /// - /// If any of the possible taint source arguments is tainted, all of the - /// destination arguments should also be tainted. Use InvalidArgIndex in the - /// src list to specify that all of the arguments can introduce taint. Use - /// InvalidArgIndex in the dst arguments to signify that all the non-const - /// pointer and reference arguments might be tainted on return. If - /// ReturnValueIndex is added to the dst list, the return value will be - /// tainted. - struct TaintPropagationRule { - using PropagationFuncType = bool (*)(bool IsTainted, const CallEvent &Call, - CheckerContext &C); - - /// List of arguments which can be taint sources and should be checked. - ArgVector SrcArgs; - /// List of arguments which should be tainted on function return. - ArgVector DstArgs; - /// Index for the first variadic parameter if exist. - unsigned VariadicIndex; - /// Show when a function has variadic parameters. If it has, it marks all - /// of them as source or destination. + struct Propagation : Common { + ArgVecTy SrcArgs; + ArgVecTy DstArgs; VariadicType VarType; - /// Special function for tainted source determination. If defined, it can - /// override the default behavior. - PropagationFuncType PropagationFunc; - - TaintPropagationRule() - : VariadicIndex(InvalidArgIndex), VarType(VariadicType::None), - PropagationFunc(nullptr) {} - - TaintPropagationRule(ArgVector &&Src, ArgVector &&Dst, - VariadicType Var = VariadicType::None, - unsigned VarIndex = InvalidArgIndex, - PropagationFuncType Func = nullptr) - : SrcArgs(std::move(Src)), DstArgs(std::move(Dst)), - VariadicIndex(VarIndex), VarType(Var), PropagationFunc(Func) {} - - /// Get the propagation rule for a given function. - static TaintPropagationRule - getTaintPropagationRule(const NameRuleMap &CustomPropagations, - const FunctionData &FData, CheckerContext &C); - - void addSrcArg(unsigned A) { SrcArgs.push_back(A); } - void addDstArg(unsigned A) { DstArgs.push_back(A); } - - bool isNull() const { - return SrcArgs.empty() && DstArgs.empty() && - VariadicType::None == VarType; - } + ArgIdxTy VarIndex; + }; - bool isDestinationArgument(unsigned ArgNum) const { - return llvm::is_contained(DstArgs, ArgNum); - } + std::vector<Propagation> Propagations; + std::vector<Filter> Filters; + std::vector<Sink> Sinks; - static bool isTaintedOrPointsToTainted(const Expr *E, - const ProgramStateRef &State, - CheckerContext &C) { - if (isTainted(State, E, C.getLocationContext()) || isStdin(E, C)) - return true; + TaintConfiguration() = default; + TaintConfiguration(const TaintConfiguration &) = default; + TaintConfiguration(TaintConfiguration &&) = default; + TaintConfiguration &operator=(const TaintConfiguration &) = default; + TaintConfiguration &operator=(TaintConfiguration &&) = default; +}; - if (!E->getType().getTypePtr()->isPointerType()) - return false; +struct GenericTaintRuleParser { + GenericTaintRuleParser(CheckerManager &Mgr) : Mgr(Mgr) {} + /// Container type used to gather call identification objects grouped into + /// pairs with their corresponding taint rules. It is temporary as it is used + /// to finally initialize RuleLookupTy, which is considered to be immutable. + using RulesContTy = std::vector<std::pair<CallDescription, GenericTaintRule>>; + RulesContTy parseConfiguration(const std::string &Option, + TaintConfiguration &&Config) const; - Optional<SVal> V = getPointeeOf(C, E); - return (V && isTainted(State, *V)); - } +private: + using NamePartsTy = llvm::SmallVector<SmallString<32>, 2>; - /// Pre-process a function which propagates taint according to the - /// taint rule. - ProgramStateRef process(const CallEvent &Call, CheckerContext &C) const; + /// Validate part of the configuration, which contains a list of argument + /// indexes. + void validateArgVector(const std::string &Option, const ArgVecTy &Args) const; - // Functions for custom taintedness propagation. - static bool postSocket(bool IsTainted, const CallEvent &Call, - CheckerContext &C); - }; + template <typename Config> static NamePartsTy parseNameParts(const Config &C); - /// Defines a map between the propagation function's name, scope - /// and TaintPropagationRule. - NameRuleMap CustomPropagations; + // Takes the config and creates a CallDescription for it and associates a Rule + // with that. + template <typename Config> + static void consumeRulesFromConfig(const Config &C, GenericTaintRule &&Rule, + RulesContTy &Rules); - /// Defines a map between the filter function's name, scope and filtering - /// args. - NameArgMap CustomFilters; + void parseConfig(const std::string &Option, TaintConfiguration::Sink &&P, + RulesContTy &Rules) const; + void parseConfig(const std::string &Option, TaintConfiguration::Filter &&P, + RulesContTy &Rules) const; + void parseConfig(const std::string &Option, + TaintConfiguration::Propagation &&P, + RulesContTy &Rules) const; - /// Defines a map between the sink function's name, scope and sinking args. - NameArgMap CustomSinks; + CheckerManager &Mgr; }; -const unsigned GenericTaintChecker::ReturnValueIndex; -const unsigned GenericTaintChecker::InvalidArgIndex; +class GenericTaintChecker : public Checker<check::PreCall, check::PostCall> { +public: + static void *getTag() { + static int Tag; + return &Tag; + } -// FIXME: these lines can be removed in C++17 -constexpr llvm::StringLiteral GenericTaintChecker::MsgUncontrolledFormatString; -constexpr llvm::StringLiteral GenericTaintChecker::MsgSanitizeSystemArgs; -constexpr llvm::StringLiteral GenericTaintChecker::MsgTaintedBufferSize; -constexpr llvm::StringLiteral GenericTaintChecker::MsgCustomSink; -} // end of anonymous namespace + void checkPreCall(const CallEvent &Call, CheckerContext &C) const; + void checkPostCall(const CallEvent &Call, CheckerContext &C) const; -using TaintConfig = GenericTaintChecker::TaintConfiguration; + void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, + const char *Sep) const override; -LLVM_YAML_IS_SEQUENCE_VECTOR(TaintConfig::Propagation) -LLVM_YAML_IS_SEQUENCE_VECTOR(TaintConfig::NameScopeArgs) + /// Generate a report if the expression is tainted or points to tainted data. + bool generateReportIfTainted(const Expr *E, StringRef Msg, + CheckerContext &C) const; + +private: + const BugType BT{this, "Use of Untrusted Data", "Untrusted Data"}; + + bool checkUncontrolledFormatString(const CallEvent &Call, + CheckerContext &C) const; + + void taintUnsafeSocketProtocol(const CallEvent &Call, + CheckerContext &C) const; + + /// Default taint rules are initilized with the help of a CheckerContext to + /// access the names of built-in functions like memcpy. + void initTaintRules(CheckerContext &C) const; + + /// CallDescription currently cannot restrict matches to the global namespace + /// only, which is why multiple CallDescriptionMaps are used, as we want to + /// disambiguate global C functions from functions inside user-defined + /// namespaces. + // TODO: Remove separation to simplify matching logic once CallDescriptions + // are more expressive. + + mutable Optional<RuleLookupTy> StaticTaintRules; + mutable Optional<RuleLookupTy> DynamicTaintRules; +}; +} // end of anonymous namespace + +/// YAML serialization mapping. +LLVM_YAML_IS_SEQUENCE_VECTOR(TaintConfiguration::Sink) +LLVM_YAML_IS_SEQUENCE_VECTOR(TaintConfiguration::Filter) +LLVM_YAML_IS_SEQUENCE_VECTOR(TaintConfiguration::Propagation) namespace llvm { namespace yaml { -template <> struct MappingTraits<TaintConfig> { - static void mapping(IO &IO, TaintConfig &Config) { +template <> struct MappingTraits<TaintConfiguration> { + static void mapping(IO &IO, TaintConfiguration &Config) { IO.mapOptional("Propagations", Config.Propagations); IO.mapOptional("Filters", Config.Filters); IO.mapOptional("Sinks", Config.Sinks); } }; -template <> struct MappingTraits<TaintConfig::Propagation> { - static void mapping(IO &IO, TaintConfig::Propagation &Propagation) { +template <> struct MappingTraits<TaintConfiguration::Sink> { + static void mapping(IO &IO, TaintConfiguration::Sink &Sink) { + IO.mapRequired("Name", Sink.Name); + IO.mapOptional("Scope", Sink.Scope); + IO.mapRequired("Args", Sink.SinkArgs); + } +}; + +template <> struct MappingTraits<TaintConfiguration::Filter> { + static void mapping(IO &IO, TaintConfiguration::Filter &Filter) { + IO.mapRequired("Name", Filter.Name); + IO.mapOptional("Scope", Filter.Scope); + IO.mapRequired("Args", Filter.FilterArgs); + } +}; + +template <> struct MappingTraits<TaintConfiguration::Propagation> { + static void mapping(IO &IO, TaintConfiguration::Propagation &Propagation) { IO.mapRequired("Name", Propagation.Name); IO.mapOptional("Scope", Propagation.Scope); IO.mapOptional("SrcArgs", Propagation.SrcArgs); IO.mapOptional("DstArgs", Propagation.DstArgs); - IO.mapOptional("VariadicType", Propagation.VarType, - GenericTaintChecker::VariadicType::None); - IO.mapOptional("VariadicIndex", Propagation.VarIndex, - GenericTaintChecker::InvalidArgIndex); - } -}; - -template <> struct ScalarEnumerationTraits<GenericTaintChecker::VariadicType> { - static void enumeration(IO &IO, GenericTaintChecker::VariadicType &Value) { - IO.enumCase(Value, "None", GenericTaintChecker::VariadicType::None); - IO.enumCase(Value, "Src", GenericTaintChecker::VariadicType::Src); - IO.enumCase(Value, "Dst", GenericTaintChecker::VariadicType::Dst); + IO.mapOptional("VariadicType", Propagation.VarType); + IO.mapOptional("VariadicIndex", Propagation.VarIndex); } }; -template <> struct MappingTraits<TaintConfig::NameScopeArgs> { - static void mapping(IO &IO, TaintConfig::NameScopeArgs &NSA) { - IO.mapRequired("Name", std::get<0>(NSA)); - IO.mapOptional("Scope", std::get<1>(NSA)); - IO.mapRequired("Args", std::get<2>(NSA)); +template <> struct ScalarEnumerationTraits<TaintConfiguration::VariadicType> { + static void enumeration(IO &IO, TaintConfiguration::VariadicType &Value) { + IO.enumCase(Value, "None", TaintConfiguration::VariadicType::None); + IO.enumCase(Value, "Src", TaintConfiguration::VariadicType::Src); + IO.enumCase(Value, "Dst", TaintConfiguration::VariadicType::Dst); } }; } // namespace yaml } // namespace llvm /// A set which is used to pass information from call pre-visit instruction -/// to the call post-visit. The values are unsigned integers, which are either +/// to the call post-visit. The values are signed integers, which are either /// ReturnValueIndex, or indexes of the pointer/reference argument, which /// points to data, which should be tainted on return. -REGISTER_SET_WITH_PROGRAMSTATE(TaintArgsOnPostVisit, unsigned) - -GenericTaintChecker::ArgVector -GenericTaintChecker::convertToArgVector(CheckerManager &Mgr, - const std::string &Option, - const SignedArgVector &Args) { - ArgVector Result; - for (int Arg : Args) { - if (Arg == -1) - Result.push_back(ReturnValueIndex); - else if (Arg < -1) { - Result.push_back(InvalidArgIndex); +REGISTER_SET_WITH_PROGRAMSTATE(TaintArgsOnPostVisit, ArgIdxTy) + +void GenericTaintRuleParser::validateArgVector(const std::string &Option, + const ArgVecTy &Args) const { + for (ArgIdxTy Arg : Args) { + if (Arg < ReturnValueIndex) { Mgr.reportInvalidCheckerOptionValue( - this, Option, + Mgr.getChecker<GenericTaintChecker>(), Option, "an argument number for propagation rules greater or equal to -1"); - } else - Result.push_back(static_cast<unsigned>(Arg)); + } } - return Result; } -void GenericTaintChecker::parseConfiguration(CheckerManager &Mgr, - const std::string &Option, - TaintConfiguration &&Config) { - for (auto &P : Config.Propagations) { - GenericTaintChecker::CustomPropagations.emplace( - P.Name, - std::make_pair(P.Scope, TaintPropagationRule{ - std::move(P.SrcArgs), - convertToArgVector(Mgr, Option, P.DstArgs), - P.VarType, P.VarIndex})); +template <typename Config> +GenericTaintRuleParser::NamePartsTy +GenericTaintRuleParser::parseNameParts(const Config &C) { + NamePartsTy NameParts; + if (!C.Scope.empty()) { + // If the Scope argument contains multiple "::" parts, those are considered + // namespace identifiers. + llvm::SmallVector<StringRef, 2> NSParts; + StringRef{C.Scope}.split(NSParts, "::", /*MaxSplit*/ -1, + /*KeepEmpty*/ false); + NameParts.append(NSParts.begin(), NSParts.end()); } + NameParts.emplace_back(C.Name); + return NameParts; +} - for (auto &F : Config.Filters) { - GenericTaintChecker::CustomFilters.emplace( - std::get<0>(F), - std::make_pair(std::move(std::get<1>(F)), std::move(std::get<2>(F)))); - } +template <typename Config> +void GenericTaintRuleParser::consumeRulesFromConfig(const Config &C, + GenericTaintRule &&Rule, + RulesContTy &Rules) { + NamePartsTy NameParts = parseNameParts(C); + llvm::SmallVector<const char *, 2> CallDescParts{NameParts.size()}; + llvm::transform(NameParts, CallDescParts.begin(), + [](SmallString<32> &S) { return S.c_str(); }); + Rules.emplace_back(CallDescription(CallDescParts), std::move(Rule)); +} - for (auto &S : Config.Sinks) { - GenericTaintChecker::CustomSinks.emplace( - std::get<0>(S), - std::make_pair(std::move(std::get<1>(S)), std::move(std::get<2>(S)))); - } +void GenericTaintRuleParser::parseConfig(const std::string &Option, + TaintConfiguration::Sink &&S, + RulesContTy &Rules) const { + validateArgVector(Option, S.SinkArgs); + consumeRulesFromConfig(S, GenericTaintRule::Sink(std::move(S.SinkArgs)), + Rules); } -template <typename T> -auto GenericTaintChecker::findFunctionInConfig(const ConfigDataMap<T> &Map, - const FunctionData &FData) { - auto Range = Map.equal_range(std::string(FData.Name)); - auto It = - std::find_if(Range.first, Range.second, [&FData](const auto &Entry) { - const auto &Value = Entry.second; - StringRef Scope = Value.first; - return Scope.empty() || FData.isInScope(Scope); - }); - return It != Range.second ? It : Map.end(); +void GenericTaintRuleParser::parseConfig(const std::string &Option, + TaintConfiguration::Filter &&S, + RulesContTy &Rules) const { + validateArgVector(Option, S.FilterArgs); + consumeRulesFromConfig(S, GenericTaintRule::Filter(std::move(S.FilterArgs)), + Rules); } -GenericTaintChecker::TaintPropagationRule -GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule( - const NameRuleMap &CustomPropagations, const FunctionData &FData, - CheckerContext &C) { - // TODO: Currently, we might lose precision here: we always mark a return - // value as tainted even if it's just a pointer, pointing to tainted data. +void GenericTaintRuleParser::parseConfig(const std::string &Option, + TaintConfiguration::Propagation &&P, + RulesContTy &Rules) const { + validateArgVector(Option, P.SrcArgs); + validateArgVector(Option, P.DstArgs); + bool IsSrcVariadic = P.VarType == TaintConfiguration::VariadicType::Src; + bool IsDstVariadic = P.VarType == TaintConfiguration::VariadicType::Dst; + Optional<ArgIdxTy> JustVarIndex = P.VarIndex; + + ArgSet SrcDesc(std::move(P.SrcArgs), IsSrcVariadic ? JustVarIndex : None); + ArgSet DstDesc(std::move(P.DstArgs), IsDstVariadic ? JustVarIndex : None); + + consumeRulesFromConfig( + P, GenericTaintRule::Prop(std::move(SrcDesc), std::move(DstDesc)), Rules); +} + +GenericTaintRuleParser::RulesContTy +GenericTaintRuleParser::parseConfiguration(const std::string &Option, + TaintConfiguration &&Config) const { + + RulesContTy Rules; + + for (auto &F : Config.Filters) + parseConfig(Option, std::move(F), Rules); + + for (auto &S : Config.Sinks) + parseConfig(Option, std::move(S), Rules); + for (auto &P : Config.Propagations) + parseConfig(Option, std::move(P), Rules); + + return Rules; +} + +void GenericTaintChecker::initTaintRules(CheckerContext &C) const { // Check for exact name match for functions without builtin substitutes. // Use qualified name, because these are C functions without namespace. - TaintPropagationRule Rule = - llvm::StringSwitch<TaintPropagationRule>(FData.FullName) - // Source functions - // TODO: Add support for vfscanf & family. - .Case("fdopen", {{}, {ReturnValueIndex}}) - .Case("fopen", {{}, {ReturnValueIndex}}) - .Case("freopen", {{}, {ReturnValueIndex}}) - .Case("getch", {{}, {ReturnValueIndex}}) - .Case("getchar", {{}, {ReturnValueIndex}}) - .Case("getchar_unlocked", {{}, {ReturnValueIndex}}) - .Case("gets", {{}, {0, ReturnValueIndex}}) - .Case("scanf", {{}, {}, VariadicType::Dst, 1}) - .Case("socket", {{}, - {ReturnValueIndex}, - VariadicType::None, - InvalidArgIndex, - &TaintPropagationRule::postSocket}) - .Case("wgetch", {{}, {ReturnValueIndex}}) - // Propagating functions - .Case("atoi", {{0}, {ReturnValueIndex}}) - .Case("atol", {{0}, {ReturnValueIndex}}) - .Case("atoll", {{0}, {ReturnValueIndex}}) - .Case("fgetc", {{0}, {ReturnValueIndex}}) - .Case("fgetln", {{0}, {ReturnValueIndex}}) - .Case("fgets", {{2}, {0, ReturnValueIndex}}) - .Case("fscanf", {{0}, {}, VariadicType::Dst, 2}) - .Case("sscanf", {{0}, {}, VariadicType::Dst, 2}) - .Case("getc", {{0}, {ReturnValueIndex}}) - .Case("getc_unlocked", {{0}, {ReturnValueIndex}}) - .Case("getdelim", {{3}, {0}}) - .Case("getline", {{2}, {0}}) - .Case("getw", {{0}, {ReturnValueIndex}}) - .Case("pread", {{0, 1, 2, 3}, {1, ReturnValueIndex}}) - .Case("read", {{0, 2}, {1, ReturnValueIndex}}) - .Case("strchr", {{0}, {ReturnValueIndex}}) - .Case("strrchr", {{0}, {ReturnValueIndex}}) - .Case("tolower", {{0}, {ReturnValueIndex}}) - .Case("toupper", {{0}, {ReturnValueIndex}}) - .Default({}); - - if (!Rule.isNull()) - return Rule; + + if (StaticTaintRules || DynamicTaintRules) + return; + + using RulesConstructionTy = + std::vector<std::pair<CallDescription, GenericTaintRule>>; + using TR = GenericTaintRule; + + const Builtin::Context &BI = C.getASTContext().BuiltinInfo; + + RulesConstructionTy GlobalCRules{ + // Sources + {{"fdopen"}, TR::Source({{ReturnValueIndex}})}, + {{"fopen"}, TR::Source({{ReturnValueIndex}})}, + {{"freopen"}, TR::Source({{ReturnValueIndex}})}, + {{"getch"}, TR::Source({{ReturnValueIndex}})}, + {{"getchar"}, TR::Source({{ReturnValueIndex}})}, + {{"getchar_unlocked"}, TR::Source({{ReturnValueIndex}})}, + {{"gets"}, TR::Source({{0}, ReturnValueIndex})}, + {{"scanf"}, TR::Source({{}, 1})}, + {{"wgetch"}, TR::Source({{}, ReturnValueIndex})}, + + // Props + {{"atoi"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"atol"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"atoll"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"fgetc"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"fgetln"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"fgets"}, TR::Prop({{2}}, {{0}, ReturnValueIndex})}, + {{"fscanf"}, TR::Prop({{0}}, {{}, 2})}, + {{"sscanf"}, TR::Prop({{0}}, {{}, 2})}, + {{"getc"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"getc_unlocked"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"getdelim"}, TR::Prop({{3}}, {{0}})}, + {{"getline"}, TR::Prop({{2}}, {{0}})}, + {{"getw"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"pread"}, TR::Prop({{0, 1, 2, 3}}, {{1, ReturnValueIndex}})}, + {{"read"}, TR::Prop({{0, 2}}, {{1, ReturnValueIndex}})}, + {{"strchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"strrchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"tolower"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{"toupper"}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrncat)}}, + TR::Prop({{1, 2}}, {{0, ReturnValueIndex}})}, + {{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrlcpy)}}, + TR::Prop({{1, 2}}, {{0}})}, + {{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrlcat)}}, + TR::Prop({{1, 2}}, {{0}})}, + {{CDF_MaybeBuiltin, {"snprintf"}}, + TR::Prop({{1}, 3}, {{0, ReturnValueIndex}})}, + {{CDF_MaybeBuiltin, {"sprintf"}}, + TR::Prop({{1}, 2}, {{0, ReturnValueIndex}})}, + {{CDF_MaybeBuiltin, {"strcpy"}}, + TR::Prop({{1}}, {{0, ReturnValueIndex}})}, + {{CDF_MaybeBuiltin, {"stpcpy"}}, + TR::Prop({{1}}, {{0, ReturnValueIndex}})}, + {{CDF_MaybeBuiltin, {"strcat"}}, + TR::Prop({{1}}, {{0, ReturnValueIndex}})}, + {{CDF_MaybeBuiltin, {"strdup"}}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{CDF_MaybeBuiltin, {"strdupa"}}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + {{CDF_MaybeBuiltin, {"wcsdup"}}, TR::Prop({{0}}, {{ReturnValueIndex}})}, + + // Sinks + {{"system"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)}, + {{"popen"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)}, + {{"execl"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)}, + {{"execle"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)}, + {{"execlp"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)}, + {{"execvp"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)}, + {{"execvP"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)}, + {{"execve"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)}, + {{"dlopen"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)}, + {{CDF_MaybeBuiltin, {"malloc"}}, TR::Sink({{0}}, MsgTaintedBufferSize)}, + {{CDF_MaybeBuiltin, {"calloc"}}, TR::Sink({{0}}, MsgTaintedBufferSize)}, + {{CDF_MaybeBuiltin, {"alloca"}}, TR::Sink({{0}}, MsgTaintedBufferSize)}, + {{CDF_MaybeBuiltin, {"memccpy"}}, TR::Sink({{3}}, MsgTaintedBufferSize)}, + {{CDF_MaybeBuiltin, {"realloc"}}, TR::Sink({{1}}, MsgTaintedBufferSize)}, + {{{"setproctitle"}}, TR::Sink({{0}, 1}, MsgUncontrolledFormatString)}, + {{{"setproctitle_fast"}}, + TR::Sink({{0}, 1}, MsgUncontrolledFormatString)}, + + // SinkProps + {{CDF_MaybeBuiltin, BI.getName(Builtin::BImemcpy)}, + TR::SinkProp({{2}}, {{1, 2}}, {{0, ReturnValueIndex}}, + MsgTaintedBufferSize)}, + {{CDF_MaybeBuiltin, {BI.getName(Builtin::BImemmove)}}, + TR::SinkProp({{2}}, {{1, 2}}, {{0, ReturnValueIndex}}, + MsgTaintedBufferSize)}, + {{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrncpy)}}, + TR::SinkProp({{2}}, {{1, 2}}, {{0, ReturnValueIndex}}, + MsgTaintedBufferSize)}, + {{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrndup)}}, + TR::SinkProp({{1}}, {{0, 1}}, {{ReturnValueIndex}}, + MsgTaintedBufferSize)}, + {{CDF_MaybeBuiltin, {"bcopy"}}, + TR::SinkProp({{2}}, {{0, 2}}, {{1}}, MsgTaintedBufferSize)}}; // `getenv` returns taint only in untrusted environments. - if (FData.FullName == "getenv") { - if (C.getAnalysisManager() - .getAnalyzerOptions() - .ShouldAssumeControlledEnvironment) - return {}; - return {{}, {ReturnValueIndex}}; + if (TR::UntrustedEnv(C)) { + // void setproctitle_init(int argc, char *argv[], char *envp[]) + GlobalCRules.push_back( + {{{"setproctitle_init"}}, TR::Sink({{2}}, MsgCustomSink)}); + GlobalCRules.push_back({{"getenv"}, TR::Source({{ReturnValueIndex}})}); } - assert(FData.FDecl); - - // Check if it's one of the memory setting/copying functions. - // This check is specialized but faster then calling isCLibraryFunction. - const FunctionDecl *FDecl = FData.FDecl; - unsigned BId = 0; - if ((BId = FDecl->getMemoryFunctionKind())) { - switch (BId) { - case Builtin::BImemcpy: - case Builtin::BImemmove: - case Builtin::BIstrncpy: - case Builtin::BIstrncat: - return {{1, 2}, {0, ReturnValueIndex}}; - case Builtin::BIstrlcpy: - case Builtin::BIstrlcat: - return {{1, 2}, {0}}; - case Builtin::BIstrndup: - return {{0, 1}, {ReturnValueIndex}}; - - default: - break; - } - } + StaticTaintRules.emplace(std::make_move_iterator(GlobalCRules.begin()), + std::make_move_iterator(GlobalCRules.end())); - // Process all other functions which could be defined as builtins. - if (Rule.isNull()) { - const auto OneOf = [FDecl](const auto &... Name) { - // FIXME: use fold expression in C++17 - using unused = int[]; - bool ret = false; - static_cast<void>(unused{ - 0, (ret |= CheckerContext::isCLibraryFunction(FDecl, Name), 0)...}); - return ret; - }; - if (OneOf("snprintf")) - return {{1}, {0, ReturnValueIndex}, VariadicType::Src, 3}; - if (OneOf("sprintf")) - return {{1}, {0, ReturnValueIndex}, VariadicType::Src, 2}; - if (OneOf("strcpy", "stpcpy", "strcat")) - return {{1}, {0, ReturnValueIndex}}; - if (OneOf("bcopy")) - return {{0, 2}, {1}}; - if (OneOf("strdup", "strdupa", "wcsdup")) - return {{0}, {ReturnValueIndex}}; + // User-provided taint configuration. + CheckerManager *Mgr = C.getAnalysisManager().getCheckerManager(); + assert(Mgr); + GenericTaintRuleParser ConfigParser{*Mgr}; + std::string Option{"Config"}; + StringRef ConfigFile = + Mgr->getAnalyzerOptions().getCheckerStringOption(this, Option); + llvm::Optional<TaintConfiguration> Config = + getConfiguration<TaintConfiguration>(*Mgr, this, Option, ConfigFile); + if (!Config) { + // We don't have external taint config, no parsing required. + DynamicTaintRules = RuleLookupTy{}; + return; } - // Skipping the following functions, since they might be used for cleansing or - // smart memory copy: - // - memccpy - copying until hitting a special character. + GenericTaintRuleParser::RulesContTy Rules{ + ConfigParser.parseConfiguration(Option, std::move(Config.getValue()))}; - auto It = findFunctionInConfig(CustomPropagations, FData); - if (It != CustomPropagations.end()) - return It->second.second; - return {}; + DynamicTaintRules.emplace(std::make_move_iterator(Rules.begin()), + std::make_move_iterator(Rules.end())); } void GenericTaintChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { - Optional<FunctionData> FData = FunctionData::create(Call, C); - if (!FData) - return; - - // Check for taintedness related errors first: system call, uncontrolled - // format string, tainted buffer size. - if (checkPre(Call, *FData, C)) - return; - - // Marks the function's arguments and/or return value tainted if it present in - // the list. - if (addSourcesPre(Call, *FData, C)) - return; - - addFiltersPre(Call, *FData, C); + initTaintRules(C); + + // FIXME: this should be much simpler. + if (const auto *Rule = + Call.isGlobalCFunction() ? StaticTaintRules->lookup(Call) : nullptr) + Rule->process(*this, Call, C); + else if (const auto *Rule = DynamicTaintRules->lookup(Call)) + Rule->process(*this, Call, C); + + // FIXME: These edge cases are to be eliminated from here eventually. + // + // Additional check that is not supported by CallDescription. + // TODO: Make CallDescription be able to match attributes such as printf-like + // arguments. + checkUncontrolledFormatString(Call, C); + + // TODO: Modeling sockets should be done in a specific checker. + // Socket is a source, which taints the return value. + taintUnsafeSocketProtocol(Call, C); } void GenericTaintChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { // Set the marked values as tainted. The return value only accessible from // checkPostStmt. - propagateFromPre(Call, C); -} - -void GenericTaintChecker::printState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep) const { - printTaint(State, Out, NL, Sep); -} - -bool GenericTaintChecker::addSourcesPre(const CallEvent &Call, - const FunctionData &FData, - CheckerContext &C) const { - // First, try generating a propagation rule for this function. - TaintPropagationRule Rule = TaintPropagationRule::getTaintPropagationRule( - this->CustomPropagations, FData, C); - if (!Rule.isNull()) { - ProgramStateRef State = Rule.process(Call, C); - if (State) { - C.addTransition(State); - return true; - } - } - return false; -} - -bool GenericTaintChecker::addFiltersPre(const CallEvent &Call, - const FunctionData &FData, - CheckerContext &C) const { - auto It = findFunctionInConfig(CustomFilters, FData); - if (It == CustomFilters.end()) - return false; - - ProgramStateRef State = C.getState(); - const auto &Value = It->second; - const ArgVector &Args = Value.second; - for (unsigned ArgNum : Args) { - if (ArgNum >= Call.getNumArgs()) - continue; - - const Expr *Arg = Call.getArgExpr(ArgNum); - Optional<SVal> V = getPointeeOf(C, Arg); - if (V) - State = removeTaint(State, *V); - } - - if (State != C.getState()) { - C.addTransition(State); - return true; - } - return false; -} - -bool GenericTaintChecker::propagateFromPre(const CallEvent &Call, - CheckerContext &C) { ProgramStateRef State = C.getState(); // Depending on what was tainted at pre-visit, we determined a set of @@ -616,9 +689,9 @@ bool GenericTaintChecker::propagateFromPre(const CallEvent &Call, // stored in the state as TaintArgsOnPostVisit set. TaintArgsOnPostVisitTy TaintArgs = State->get<TaintArgsOnPostVisit>(); if (TaintArgs.isEmpty()) - return false; + return; - for (unsigned ArgNum : TaintArgs) { + for (ArgIdxTy ArgNum : TaintArgs) { // Special handling for the tainted return value. if (ArgNum == ReturnValueIndex) { State = addTaint(State, Call.getReturnValue()); @@ -627,234 +700,147 @@ bool GenericTaintChecker::propagateFromPre(const CallEvent &Call, // The arguments are pointer arguments. The data they are pointing at is // tainted after the call. - if (Call.getNumArgs() < (ArgNum + 1)) - return false; - const Expr *Arg = Call.getArgExpr(ArgNum); - Optional<SVal> V = getPointeeOf(C, Arg); - if (V) + if (auto V = getPointeeOf(C, Call.getArgSVal(ArgNum))) State = addTaint(State, *V); } // Clear up the taint info from the state. State = State->remove<TaintArgsOnPostVisit>(); - - if (State != C.getState()) { - C.addTransition(State); - return true; - } - return false; -} - -bool GenericTaintChecker::checkPre(const CallEvent &Call, - const FunctionData &FData, - CheckerContext &C) const { - if (checkUncontrolledFormatString(Call, C)) - return true; - - if (checkSystemCall(Call, FData.Name, C)) - return true; - - if (checkTaintedBufferSize(Call, C)) - return true; - - return checkCustomSinks(Call, FData, C); + C.addTransition(State); } -Optional<SVal> GenericTaintChecker::getPointeeOf(CheckerContext &C, - const Expr *Arg) { - ProgramStateRef State = C.getState(); - SVal AddrVal = C.getSVal(Arg->IgnoreParens()); - if (AddrVal.isUnknownOrUndef()) - return None; - - Optional<Loc> AddrLoc = AddrVal.getAs<Loc>(); - if (!AddrLoc) - return None; - - QualType ArgTy = Arg->getType().getCanonicalType(); - if (!ArgTy->isPointerType()) - return State->getSVal(*AddrLoc); - - QualType ValTy = ArgTy->getPointeeType(); - - // Do not dereference void pointers. Treat them as byte pointers instead. - // FIXME: we might want to consider more than just the first byte. - if (ValTy->isVoidType()) - ValTy = C.getASTContext().CharTy; - - return State->getSVal(*AddrLoc, ValTy); +void GenericTaintChecker::printState(raw_ostream &Out, ProgramStateRef State, + const char *NL, const char *Sep) const { + printTaint(State, Out, NL, Sep); } -ProgramStateRef -GenericTaintChecker::TaintPropagationRule::process(const CallEvent &Call, - CheckerContext &C) const { +void GenericTaintRule::process(const GenericTaintChecker &Checker, + const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); + const ArgIdxTy CallNumArgs = fromArgumentCount(Call.getNumArgs()); - // Check for taint in arguments. - bool IsTainted = true; - for (unsigned ArgNum : SrcArgs) { - if (ArgNum >= Call.getNumArgs()) - continue; - - if ((IsTainted = - isTaintedOrPointsToTainted(Call.getArgExpr(ArgNum), State, C))) - break; - } - - // Check for taint in variadic arguments. - if (!IsTainted && VariadicType::Src == VarType) { - // Check if any of the arguments is tainted - for (unsigned i = VariadicIndex; i < Call.getNumArgs(); ++i) { - if ((IsTainted = - isTaintedOrPointsToTainted(Call.getArgExpr(i), State, C))) - break; + /// Iterate every call argument, and get their corresponding Expr and SVal. + const auto ForEachCallArg = [&C, &Call, CallNumArgs](auto &&Fun) { + for (ArgIdxTy I = ReturnValueIndex; I < CallNumArgs; ++I) { + const Expr *E = GetArgExpr(I, Call); + Fun(I, E, C.getSVal(E)); } - } + }; - if (PropagationFunc) - IsTainted = PropagationFunc(IsTainted, Call, C); + /// Check for taint sinks. + ForEachCallArg([this, &Checker, &C, &State](ArgIdxTy I, const Expr *E, SVal) { + if (SinkArgs.contains(I) && isTaintedOrPointsToTainted(E, State, C)) + Checker.generateReportIfTainted(E, SinkMsg.getValueOr(MsgCustomSink), C); + }); + + /// Check for taint filters. + ForEachCallArg([this, &C, &State](ArgIdxTy I, const Expr *E, SVal S) { + if (FilterArgs.contains(I)) { + State = removeTaint(State, S); + if (auto P = getPointeeOf(C, S)) + State = removeTaint(State, *P); + } + }); + + /// Check for taint propagation sources. + /// A rule is relevant if PropSrcArgs is empty, or if any of its signified + /// args are tainted in context of the current CallEvent. + bool IsMatching = PropSrcArgs.isEmpty(); + ForEachCallArg( + [this, &C, &IsMatching, &State](ArgIdxTy I, const Expr *E, SVal) { + IsMatching = IsMatching || (PropSrcArgs.contains(I) && + isTaintedOrPointsToTainted(E, State, C)); + }); - if (!IsTainted) - return State; + if (!IsMatching) + return; - // Mark the arguments which should be tainted after the function returns. - for (unsigned ArgNum : DstArgs) { - // Should mark the return value? - if (ArgNum == ReturnValueIndex) { - State = State->add<TaintArgsOnPostVisit>(ReturnValueIndex); - continue; - } + const auto WouldEscape = [](SVal V, QualType Ty) -> bool { + if (!V.getAs<Loc>()) + return false; - if (ArgNum >= Call.getNumArgs()) - continue; + const bool IsNonConstRef = Ty->isReferenceType() && !Ty.isConstQualified(); + const bool IsNonConstPtr = + Ty->isPointerType() && !Ty->getPointeeType().isConstQualified(); - // Mark the given argument. - State = State->add<TaintArgsOnPostVisit>(ArgNum); - } + return IsNonConstRef || IsNonConstPtr; + }; - // Mark all variadic arguments tainted if present. - if (VariadicType::Dst == VarType) { - // For all pointer and references that were passed in: - // If they are not pointing to const data, mark data as tainted. - // TODO: So far we are just going one level down; ideally we'd need to - // recurse here. - for (unsigned i = VariadicIndex; i < Call.getNumArgs(); ++i) { - const Expr *Arg = Call.getArgExpr(i); - // Process pointer argument. - const Type *ArgTy = Arg->getType().getTypePtr(); - QualType PType = ArgTy->getPointeeType(); - if ((!PType.isNull() && !PType.isConstQualified()) || - (ArgTy->isReferenceType() && !Arg->getType().isConstQualified())) { - State = State->add<TaintArgsOnPostVisit>(i); - } - } - } + /// Propagate taint where it is necessary. + ForEachCallArg( + [this, &State, WouldEscape](ArgIdxTy I, const Expr *E, SVal V) { + if (PropDstArgs.contains(I)) + State = State->add<TaintArgsOnPostVisit>(I); + + // TODO: We should traverse all reachable memory regions via the + // escaping parameter. Instead of doing that we simply mark only the + // referred memory region as tainted. + if (WouldEscape(V, E->getType())) + State = State->add<TaintArgsOnPostVisit>(I); + }); - return State; + C.addTransition(State); } -// If argument 0(protocol domain) is network, the return value should get taint. -bool GenericTaintChecker::TaintPropagationRule::postSocket( - bool /*IsTainted*/, const CallEvent &Call, CheckerContext &C) { - SourceLocation DomLoc = Call.getArgExpr(0)->getExprLoc(); - StringRef DomName = C.getMacroNameOrSpelling(DomLoc); - // White list the internal communication protocols. - if (DomName.equals("AF_SYSTEM") || DomName.equals("AF_LOCAL") || - DomName.equals("AF_UNIX") || DomName.equals("AF_RESERVED_36")) - return false; - return true; +bool GenericTaintRule::UntrustedEnv(CheckerContext &C) { + return !C.getAnalysisManager() + .getAnalyzerOptions() + .ShouldAssumeControlledEnvironment; } -bool GenericTaintChecker::isStdin(const Expr *E, CheckerContext &C) { - ProgramStateRef State = C.getState(); - SVal Val = C.getSVal(E); - - // stdin is a pointer, so it would be a region. - const MemRegion *MemReg = Val.getAsRegion(); +bool GenericTaintChecker::generateReportIfTainted(const Expr *E, StringRef Msg, + CheckerContext &C) const { + assert(E); + Optional<SVal> TaintedSVal{getTaintedPointeeOrPointer(C, C.getSVal(E))}; - // The region should be symbolic, we do not know it's value. - const auto *SymReg = dyn_cast_or_null<SymbolicRegion>(MemReg); - if (!SymReg) + if (!TaintedSVal) return false; - // Get it's symbol and find the declaration region it's pointing to. - const auto *Sm = dyn_cast<SymbolRegionValue>(SymReg->getSymbol()); - if (!Sm) - return false; - const auto *DeclReg = dyn_cast_or_null<DeclRegion>(Sm->getRegion()); - if (!DeclReg) - return false; - - // This region corresponds to a declaration, find out if it's a global/extern - // variable named stdin with the proper type. - if (const auto *D = dyn_cast_or_null<VarDecl>(DeclReg->getDecl())) { - D = D->getCanonicalDecl(); - if (D->getName().contains("stdin") && D->isExternC()) { - const auto *PtrTy = dyn_cast<PointerType>(D->getType().getTypePtr()); - if (PtrTy && PtrTy->getPointeeType().getCanonicalType() == - C.getASTContext().getFILEType().getCanonicalType()) - return true; - } + // Generate diagnostic. + if (ExplodedNode *N = C.generateNonFatalErrorNode()) { + auto report = std::make_unique<PathSensitiveBugReport>(BT, Msg, N); + report->addRange(E->getSourceRange()); + report->addVisitor(std::make_unique<TaintBugVisitor>(*TaintedSVal)); + C.emitReport(std::move(report)); + return true; } return false; } +/// TODO: remove checking for printf format attributes and socket whitelisting +/// from GenericTaintChecker, and that means the following functions: +/// getPrintfFormatArgumentNum, +/// GenericTaintChecker::checkUncontrolledFormatString, +/// GenericTaintChecker::taintUnsafeSocketProtocol + static bool getPrintfFormatArgumentNum(const CallEvent &Call, const CheckerContext &C, - unsigned &ArgNum) { + ArgIdxTy &ArgNum) { // Find if the function contains a format string argument. // Handles: fprintf, printf, sprintf, snprintf, vfprintf, vprintf, vsprintf, // vsnprintf, syslog, custom annotated functions. - const FunctionDecl *FDecl = Call.getDecl()->getAsFunction(); + const Decl *CallDecl = Call.getDecl(); + if (!CallDecl) + return false; + const FunctionDecl *FDecl = CallDecl->getAsFunction(); if (!FDecl) return false; + + const ArgIdxTy CallNumArgs = fromArgumentCount(Call.getNumArgs()); + for (const auto *Format : FDecl->specific_attrs<FormatAttr>()) { ArgNum = Format->getFormatIdx() - 1; - if ((Format->getType()->getName() == "printf") && - Call.getNumArgs() > ArgNum) + if ((Format->getType()->getName() == "printf") && CallNumArgs > ArgNum) return true; } - // Or if a function is named setproctitle (this is a heuristic). - if (C.getCalleeName(FDecl).contains("setproctitle")) { - ArgNum = 0; - return true; - } - - return false; -} - -bool GenericTaintChecker::generateReportIfTainted(const Expr *E, StringRef Msg, - CheckerContext &C) const { - assert(E); - - // Check for taint. - ProgramStateRef State = C.getState(); - Optional<SVal> PointedToSVal = getPointeeOf(C, E); - SVal TaintedSVal; - if (PointedToSVal && isTainted(State, *PointedToSVal)) - TaintedSVal = *PointedToSVal; - else if (isTainted(State, E, C.getLocationContext())) - TaintedSVal = C.getSVal(E); - else - return false; - - // Generate diagnostic. - if (ExplodedNode *N = C.generateNonFatalErrorNode()) { - initBugType(); - auto report = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N); - report->addRange(E->getSourceRange()); - report->addVisitor(std::make_unique<TaintBugVisitor>(TaintedSVal)); - C.emitReport(std::move(report)); - return true; - } return false; } bool GenericTaintChecker::checkUncontrolledFormatString( const CallEvent &Call, CheckerContext &C) const { // Check if the function contains a format string argument. - unsigned ArgNum = 0; + ArgIdxTy ArgNum = 0; if (!getPrintfFormatArgumentNum(Call, C, ArgNum)) return false; @@ -864,102 +850,32 @@ bool GenericTaintChecker::checkUncontrolledFormatString( MsgUncontrolledFormatString, C); } -bool GenericTaintChecker::checkSystemCall(const CallEvent &Call, StringRef Name, - CheckerContext &C) const { - // TODO: It might make sense to run this check on demand. In some cases, - // we should check if the environment has been cleansed here. We also might - // need to know if the user was reset before these calls(seteuid). - unsigned ArgNum = llvm::StringSwitch<unsigned>(Name) - .Case("system", 0) - .Case("popen", 0) - .Case("execl", 0) - .Case("execle", 0) - .Case("execlp", 0) - .Case("execv", 0) - .Case("execvp", 0) - .Case("execvP", 0) - .Case("execve", 0) - .Case("dlopen", 0) - .Default(InvalidArgIndex); - - if (ArgNum == InvalidArgIndex || Call.getNumArgs() < (ArgNum + 1)) - return false; - - return generateReportIfTainted(Call.getArgExpr(ArgNum), MsgSanitizeSystemArgs, - C); -} - -// TODO: Should this check be a part of the CString checker? -// If yes, should taint be a global setting? -bool GenericTaintChecker::checkTaintedBufferSize(const CallEvent &Call, - CheckerContext &C) const { - const auto *FDecl = Call.getDecl()->getAsFunction(); - // If the function has a buffer size argument, set ArgNum. - unsigned ArgNum = InvalidArgIndex; - unsigned BId = 0; - if ((BId = FDecl->getMemoryFunctionKind())) { - switch (BId) { - case Builtin::BImemcpy: - case Builtin::BImemmove: - case Builtin::BIstrncpy: - ArgNum = 2; - break; - case Builtin::BIstrndup: - ArgNum = 1; - break; - default: - break; - } - } +void GenericTaintChecker::taintUnsafeSocketProtocol(const CallEvent &Call, + CheckerContext &C) const { + if (Call.getNumArgs() < 1) + return; + const IdentifierInfo *ID = Call.getCalleeIdentifier(); + if (!ID) + return; + if (!ID->getName().equals("socket")) + return; - if (ArgNum == InvalidArgIndex) { - using CCtx = CheckerContext; - if (CCtx::isCLibraryFunction(FDecl, "malloc") || - CCtx::isCLibraryFunction(FDecl, "calloc") || - CCtx::isCLibraryFunction(FDecl, "alloca")) - ArgNum = 0; - else if (CCtx::isCLibraryFunction(FDecl, "memccpy")) - ArgNum = 3; - else if (CCtx::isCLibraryFunction(FDecl, "realloc")) - ArgNum = 1; - else if (CCtx::isCLibraryFunction(FDecl, "bcopy")) - ArgNum = 2; - } + SourceLocation DomLoc = Call.getArgExpr(0)->getExprLoc(); + StringRef DomName = C.getMacroNameOrSpelling(DomLoc); + // Allow internal communication protocols. + bool SafeProtocol = DomName.equals("AF_SYSTEM") || + DomName.equals("AF_LOCAL") || DomName.equals("AF_UNIX") || + DomName.equals("AF_RESERVED_36"); + if (SafeProtocol) + return; - return ArgNum != InvalidArgIndex && Call.getNumArgs() > ArgNum && - generateReportIfTainted(Call.getArgExpr(ArgNum), MsgTaintedBufferSize, - C); + C.addTransition(C.getState()->add<TaintArgsOnPostVisit>(ReturnValueIndex)); } -bool GenericTaintChecker::checkCustomSinks(const CallEvent &Call, - const FunctionData &FData, - CheckerContext &C) const { - auto It = findFunctionInConfig(CustomSinks, FData); - if (It == CustomSinks.end()) - return false; - - const auto &Value = It->second; - const GenericTaintChecker::ArgVector &Args = Value.second; - for (unsigned ArgNum : Args) { - if (ArgNum >= Call.getNumArgs()) - continue; - - if (generateReportIfTainted(Call.getArgExpr(ArgNum), MsgCustomSink, C)) - return true; - } - - return false; -} +/// Checker registration void ento::registerGenericTaintChecker(CheckerManager &Mgr) { - auto *Checker = Mgr.registerChecker<GenericTaintChecker>(); - std::string Option{"Config"}; - StringRef ConfigFile = - Mgr.getAnalyzerOptions().getCheckerStringOption(Checker, Option); - llvm::Optional<TaintConfig> Config = - getConfiguration<TaintConfig>(Mgr, Checker, Option, ConfigFile); - if (Config) - Checker->parseConfiguration(Mgr, Option, std::move(Config.getValue())); + Mgr.registerChecker<GenericTaintChecker>(); } bool ento::shouldRegisterGenericTaintChecker(const CheckerManager &mgr) { diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 10ed6149528c..57080a84451a 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1643,7 +1643,7 @@ void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call, ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0), Call, C.getState(), /*Hold=*/true, IsKnownToBeAllocatedMemory, AF_Malloc, - /*RetNullOnFailure=*/true); + /*ReturnsNullOnFailure=*/true); C.addTransition(State); } diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp index 517a5d78271b..aa70db041c76 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp @@ -23,7 +23,6 @@ using namespace clang; using namespace ento; -using llvm::APSInt; namespace { class MmapWriteExecChecker : public Checker<check::PreCall> { diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp index cd502241ef61..cf97439a468d 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp @@ -59,7 +59,7 @@ private: } // namespace static std::string getName(const CallEvent &Call) { - std::string Name = ""; + std::string Name; if (const auto *MD = dyn_cast<CXXMethodDecl>(Call.getDecl())) if (const CXXRecordDecl *RD = MD->getParent()) Name += RD->getNameAsString() + "::"; diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h index ec6a7144fa45..e35ea4ef05dd 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h @@ -17,10 +17,6 @@ #include <utility> namespace clang { -class CXXRecordDecl; -class CXXBaseSpecifier; -class FunctionDecl; -class CXXMethodDecl; class Expr; /// This function de-facto defines a set of transformations that we consider diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h index 730a59977175..753adea0d14d 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h @@ -15,7 +15,6 @@ namespace clang { class CXXBaseSpecifier; class CXXMethodDecl; class CXXRecordDecl; -class Expr; class FunctionDecl; class Type; diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Yaml.h contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Yaml.h index ec612dde3b8b..497189f4c160 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Yaml.h +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Yaml.h @@ -57,4 +57,4 @@ llvm::Optional<T> getConfiguration(CheckerManager &Mgr, Checker *Chk, } // namespace ento } // namespace clang -#endif // LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MOVE_H +#endif // LLVM_CLANG_LIB_STATICANALYZER_CHECKER_YAML_H diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index b957bec7493e..e13387fb1fc8 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -2804,7 +2804,8 @@ bool ConditionBRVisitor::patternMatch(const Expr *Ex, Out << '\'' << Lexer::getSourceText( CharSourceRange::getTokenRange(Ex->getSourceRange()), - BRC.getSourceManager(), BRC.getASTContext().getLangOpts(), 0) + BRC.getSourceManager(), BRC.getASTContext().getLangOpts(), + nullptr) << '\''; } diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 637e4edfd778..302a971a15f2 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -416,7 +416,10 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, case CK_IntegralCast: { // Delegate to SValBuilder to process. SVal V = state->getSVal(Ex, LCtx); - V = svalBuilder.evalIntegralCast(state, V, T, ExTy); + if (AMgr.options.ShouldSupportSymbolicIntegerCasts) + V = svalBuilder.evalCast(V, T, ExTy); + else + V = svalBuilder.evalIntegralCast(state, V, T, ExTy); state = state->BindExpr(CastE, LCtx, V); Bldr.generateNode(CastE, Pred, state); continue; diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index 1ccb0de92fba..8d4e0bbb7dec 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -54,11 +54,7 @@ ProgramState::ProgramState(ProgramStateManager *mgr, const Environment& env, } ProgramState::ProgramState(const ProgramState &RHS) - : llvm::FoldingSetNode(), - stateMgr(RHS.stateMgr), - Env(RHS.Env), - store(RHS.store), - GDM(RHS.GDM), + : stateMgr(RHS.stateMgr), Env(RHS.Env), store(RHS.store), GDM(RHS.GDM), refCount(0) { stateMgr->getStoreManager().incrementReferenceCount(store); } diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp index 8edcef319088..bb3261bae3bf 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -980,15 +980,19 @@ SVal SValBuilder::evalCastSubKind(nonloc::SymbolVal V, QualType CastTy, } else { // Symbol to integer, float. QualType T = Context.getCanonicalType(SE->getType()); - // If types are the same or both are integers, ignore the cast. - // FIXME: Remove this hack when we support symbolic truncation/extension. - // HACK: If both castTy and T are integers, ignore the cast. This is - // not a permanent solution. Eventually we want to precisely handle - // extension/truncation of symbolic integers. This prevents us from losing - // precision when we assign 'x = y' and 'y' is symbolic and x and y are - // different integer types. - if (haveSameType(T, CastTy)) - return V; + + // Produce SymbolCast if CastTy and T are different integers. + // NOTE: In the end the type of SymbolCast shall be equal to CastTy. + if (T->isIntegralOrEnumerationType() && + CastTy->isIntegralOrEnumerationType()) { + AnalyzerOptions &Opts = + StateMgr.getOwningEngine().getAnalysisManager().getAnalyzerOptions(); + // If appropriate option is disabled, ignore the cast. + // NOTE: ShouldSupportSymbolicIntegerCasts is `false` by default. + if (!Opts.ShouldSupportSymbolicIntegerCasts) + return V; + return simplifySymbolCast(V, CastTy); + } if (!Loc::isLocType(CastTy)) if (!IsUnknownOriginalType || !CastTy->isFloatingType() || T->isFloatingType()) @@ -1004,3 +1008,75 @@ SVal SValBuilder::evalCastSubKind(nonloc::PointerToMember V, QualType CastTy, // Member pointer to whatever. return V; } + +SVal clang::ento::SValBuilder::simplifySymbolCast(nonloc::SymbolVal V, + QualType CastTy) { + // We use seven conditions to recognize a simplification case. + // For the clarity let `CastTy` be `C`, SE->getType() - `T`, root type - `R`, + // prefix `u` for unsigned, `s` for signed, no prefix - any sign: + // E.g. (char)(short)(uint x) + // ( sC )( sT )( uR x) + // + // C === R (the same type) + // (char)(char x) -> (char x) + // (long)(long x) -> (long x) + // Note: Comparisons operators below are for bit width. + // C == T + // (short)(short)(int x) -> (short)(int x) + // (int)(long)(char x) -> (int)(char x) (sizeof(long) == sizeof(int)) + // (long)(ullong)(char x) -> (long)(char x) (sizeof(long) == sizeof(ullong)) + // C < T + // (short)(int)(char x) -> (short)(char x) + // (char)(int)(short x) -> (char)(short x) + // (short)(int)(short x) -> (short x) + // C > T > uR + // (int)(short)(uchar x) -> (int)(uchar x) + // (uint)(short)(uchar x) -> (uint)(uchar x) + // (int)(ushort)(uchar x) -> (int)(uchar x) + // C > sT > sR + // (int)(short)(char x) -> (int)(char x) + // (uint)(short)(char x) -> (uint)(char x) + // C > sT == sR + // (int)(char)(char x) -> (int)(char x) + // (uint)(short)(short x) -> (uint)(short x) + // C > uT == uR + // (int)(uchar)(uchar x) -> (int)(uchar x) + // (uint)(ushort)(ushort x) -> (uint)(ushort x) + // (llong)(ulong)(uint x) -> (llong)(uint x) (sizeof(ulong) == sizeof(uint)) + + SymbolRef SE = V.getSymbol(); + QualType T = Context.getCanonicalType(SE->getType()); + + if (T == CastTy) + return V; + + if (!isa<SymbolCast>(SE)) + return makeNonLoc(SE, T, CastTy); + + SymbolRef RootSym = cast<SymbolCast>(SE)->getOperand(); + QualType RT = RootSym->getType().getCanonicalType(); + + BasicValueFactory &BVF = getBasicValueFactory(); + APSIntType CTy = BVF.getAPSIntType(CastTy); + APSIntType TTy = BVF.getAPSIntType(T); + + const auto WC = CTy.getBitWidth(); + const auto WT = TTy.getBitWidth(); + + if (WC <= WT) { + const bool isSameType = (RT == CastTy); + if (isSameType) + return nonloc::SymbolVal(RootSym); + return makeNonLoc(RootSym, RT, CastTy); + } + + APSIntType RTy = BVF.getAPSIntType(RT); + const auto WR = RTy.getBitWidth(); + const bool UT = TTy.isUnsigned(); + const bool UR = RTy.isUnsigned(); + + if (((WT > WR) && (UR || !UT)) || ((WT == WR) && (UT == UR))) + return makeNonLoc(RootSym, RT, CastTy); + + return makeNonLoc(SE, T, CastTy); +} diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index dad8a7b3caae..0bd47ced15a5 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -432,7 +432,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state, return evalCast(lhs, resultTy, QualType{}); } - while (1) { + while (true) { switch (lhs.getSubKind()) { default: return makeSymExprValNN(op, lhs, rhs, resultTy); diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index f6ddcb763f9d..b152f9d80ef5 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -143,7 +143,7 @@ public: } if (Opts->PrintStats || Opts->ShouldSerializeStats) { - llvm::EnableStatistics(/* PrintOnExit= */ false); + llvm::EnableStatistics(/* DoPrintOnExit= */ false); } if (Opts->ShouldDisplayMacroExpansions) diff --git contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/ModelInjector.h contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/ModelInjector.h index d2016c3b112c..4db26028362f 100644 --- contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/ModelInjector.h +++ contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/ModelInjector.h @@ -29,10 +29,7 @@ namespace clang { class CompilerInstance; -class ASTUnit; -class ASTReader; class NamedDecl; -class Module; namespace ento { class ModelInjector : public CodeInjector { diff --git contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp index acceec690c11..80a70252721d 100644 --- contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp @@ -16,10 +16,10 @@ using namespace clang; using namespace tooling; using namespace dependencies; -llvm::ErrorOr<llvm::vfs::Status> -CachedFileSystemEntry::initFile(StringRef Filename, llvm::vfs::FileSystem &FS) { +llvm::ErrorOr<DependencyScanningWorkerFilesystem::TentativeEntry> +DependencyScanningWorkerFilesystem::readFile(StringRef Filename) { // Load the file and its content from the file system. - auto MaybeFile = FS.openFileForRead(Filename); + auto MaybeFile = getUnderlyingFS().openFileForRead(Filename); if (!MaybeFile) return MaybeFile.getError(); auto File = std::move(*MaybeFile); @@ -34,24 +34,43 @@ CachedFileSystemEntry::initFile(StringRef Filename, llvm::vfs::FileSystem &FS) { return MaybeBuffer.getError(); auto Buffer = std::move(*MaybeBuffer); - OriginalContents = std::move(Buffer); - return Stat; + // If the file size changed between read and stat, pretend it didn't. + if (Stat.getSize() != Buffer->getBufferSize()) + Stat = llvm::vfs::Status::copyWithNewSize(Stat, Buffer->getBufferSize()); + + return TentativeEntry(Stat, std::move(Buffer)); } -void CachedFileSystemEntry::minimizeFile() { - assert(OriginalContents && "minimizing missing contents"); +EntryRef DependencyScanningWorkerFilesystem::minimizeIfNecessary( + const CachedFileSystemEntry &Entry, StringRef Filename, bool Disable) { + if (Entry.isError() || Entry.isDirectory() || Disable || + !shouldMinimize(Filename, Entry.getUniqueID())) + return EntryRef(/*Minimized=*/false, Filename, Entry); + + CachedFileContents *Contents = Entry.getContents(); + assert(Contents && "contents not initialized"); + + // Double-checked locking. + if (Contents->MinimizedAccess.load()) + return EntryRef(/*Minimized=*/true, Filename, Entry); + + std::lock_guard<std::mutex> GuardLock(Contents->ValueLock); + + // Double-checked locking. + if (Contents->MinimizedAccess.load()) + return EntryRef(/*Minimized=*/true, Filename, Entry); llvm::SmallString<1024> MinimizedFileContents; // Minimize the file down to directives that might affect the dependencies. SmallVector<minimize_source_to_dependency_directives::Token, 64> Tokens; - if (minimizeSourceToDependencyDirectives(OriginalContents->getBuffer(), + if (minimizeSourceToDependencyDirectives(Contents->Original->getBuffer(), MinimizedFileContents, Tokens)) { // FIXME: Propagate the diagnostic if desired by the client. // Use the original file if the minimization failed. - MinimizedContentsStorage = - llvm::MemoryBuffer::getMemBuffer(*OriginalContents); - MinimizedContentsAccess.store(MinimizedContentsStorage.get()); - return; + Contents->MinimizedStorage = + llvm::MemoryBuffer::getMemBuffer(*Contents->Original); + Contents->MinimizedAccess.store(Contents->MinimizedStorage.get()); + return EntryRef(/*Minimized=*/true, Filename, Entry); } // The contents produced by the minimizer must be null terminated. @@ -74,16 +93,17 @@ void CachedFileSystemEntry::minimizeFile() { } Mapping[Range.Offset] = Range.Length; } - PPSkippedRangeMapping = std::move(Mapping); + Contents->PPSkippedRangeMapping = std::move(Mapping); - MinimizedContentsStorage = std::make_unique<llvm::SmallVectorMemoryBuffer>( + Contents->MinimizedStorage = std::make_unique<llvm::SmallVectorMemoryBuffer>( std::move(MinimizedFileContents)); - // The algorithm in `getOrCreateFileSystemEntry` uses the presence of - // minimized contents to decide whether an entry is up-to-date or not. - // If it is up-to-date, the skipped range mappings must be already computed. - // This is why we need to store the minimized contents **after** storing the - // skipped range mappings. Failing to do so would lead to a data race. - MinimizedContentsAccess.store(MinimizedContentsStorage.get()); + // This function performed double-checked locking using `MinimizedAccess`. + // Assigning it must be the last thing this function does. If we were to + // assign it before `PPSkippedRangeMapping`, other threads may skip the + // critical section (`MinimizedAccess != nullptr`) and access the mappings + // that are about to be initialized, leading to a data race. + Contents->MinimizedAccess.store(Contents->MinimizedStorage.get()); + return EntryRef(/*Minimized=*/true, Filename, Entry); } DependencyScanningFilesystemSharedCache:: @@ -98,12 +118,70 @@ DependencyScanningFilesystemSharedCache:: CacheShards = std::make_unique<CacheShard[]>(NumShards); } -DependencyScanningFilesystemSharedCache::SharedFileSystemEntry & -DependencyScanningFilesystemSharedCache::get(StringRef Key) { - CacheShard &Shard = CacheShards[llvm::hash_value(Key) % NumShards]; - std::lock_guard<std::mutex> LockGuard(Shard.CacheLock); - auto It = Shard.Cache.try_emplace(Key); - return It.first->getValue(); +DependencyScanningFilesystemSharedCache::CacheShard & +DependencyScanningFilesystemSharedCache::getShardForFilename( + StringRef Filename) const { + return CacheShards[llvm::hash_value(Filename) % NumShards]; +} + +DependencyScanningFilesystemSharedCache::CacheShard & +DependencyScanningFilesystemSharedCache::getShardForUID( + llvm::sys::fs::UniqueID UID) const { + auto Hash = llvm::hash_combine(UID.getDevice(), UID.getFile()); + return CacheShards[Hash % NumShards]; +} + +const CachedFileSystemEntry * +DependencyScanningFilesystemSharedCache::CacheShard::findEntryByFilename( + StringRef Filename) const { + std::lock_guard<std::mutex> LockGuard(CacheLock); + auto It = EntriesByFilename.find(Filename); + return It == EntriesByFilename.end() ? nullptr : It->getValue(); +} + +const CachedFileSystemEntry * +DependencyScanningFilesystemSharedCache::CacheShard::findEntryByUID( + llvm::sys::fs::UniqueID UID) const { + std::lock_guard<std::mutex> LockGuard(CacheLock); + auto It = EntriesByUID.find(UID); + return It == EntriesByUID.end() ? nullptr : It->getSecond(); +} + +const CachedFileSystemEntry & +DependencyScanningFilesystemSharedCache::CacheShard:: + getOrEmplaceEntryForFilename(StringRef Filename, + llvm::ErrorOr<llvm::vfs::Status> Stat) { + std::lock_guard<std::mutex> LockGuard(CacheLock); + auto Insertion = EntriesByFilename.insert({Filename, nullptr}); + if (Insertion.second) + Insertion.first->second = + new (EntryStorage.Allocate()) CachedFileSystemEntry(std::move(Stat)); + return *Insertion.first->second; +} + +const CachedFileSystemEntry & +DependencyScanningFilesystemSharedCache::CacheShard::getOrEmplaceEntryForUID( + llvm::sys::fs::UniqueID UID, llvm::vfs::Status Stat, + std::unique_ptr<llvm::MemoryBuffer> Contents) { + std::lock_guard<std::mutex> LockGuard(CacheLock); + auto Insertion = EntriesByUID.insert({UID, nullptr}); + if (Insertion.second) { + CachedFileContents *StoredContents = nullptr; + if (Contents) + StoredContents = new (ContentsStorage.Allocate()) + CachedFileContents(std::move(Contents)); + Insertion.first->second = new (EntryStorage.Allocate()) + CachedFileSystemEntry(std::move(Stat), StoredContents); + } + return *Insertion.first->second; +} + +const CachedFileSystemEntry & +DependencyScanningFilesystemSharedCache::CacheShard:: + getOrInsertEntryForFilename(StringRef Filename, + const CachedFileSystemEntry &Entry) { + std::lock_guard<std::mutex> LockGuard(CacheLock); + return *EntriesByFilename.insert({Filename, &Entry}).first->getValue(); } /// Whitelist file extensions that should be minimized, treating no extension as @@ -133,68 +211,79 @@ static bool shouldCacheStatFailures(StringRef Filename) { } void DependencyScanningWorkerFilesystem::disableMinimization( - StringRef RawFilename) { - llvm::SmallString<256> Filename; - llvm::sys::path::native(RawFilename, Filename); - NotToBeMinimized.insert(Filename); + StringRef Filename) { + // Since we're not done setting up `NotToBeMinimized` yet, we need to disable + // minimization explicitly. + if (llvm::ErrorOr<EntryRef> Result = + getOrCreateFileSystemEntry(Filename, /*DisableMinimization=*/true)) + NotToBeMinimized.insert(Result->getStatus().getUniqueID()); } -bool DependencyScanningWorkerFilesystem::shouldMinimize(StringRef RawFilename) { - if (!shouldMinimizeBasedOnExtension(RawFilename)) - return false; - - llvm::SmallString<256> Filename; - llvm::sys::path::native(RawFilename, Filename); - return !NotToBeMinimized.contains(Filename); +bool DependencyScanningWorkerFilesystem::shouldMinimize( + StringRef Filename, llvm::sys::fs::UniqueID UID) { + return shouldMinimizeBasedOnExtension(Filename) && + !NotToBeMinimized.contains(UID); } -void CachedFileSystemEntry::init(llvm::ErrorOr<llvm::vfs::Status> &&MaybeStatus, - StringRef Filename, - llvm::vfs::FileSystem &FS) { - if (!MaybeStatus || MaybeStatus->isDirectory()) - MaybeStat = std::move(MaybeStatus); - else - MaybeStat = initFile(Filename, FS); +const CachedFileSystemEntry & +DependencyScanningWorkerFilesystem::getOrEmplaceSharedEntryForUID( + TentativeEntry TEntry) { + auto &Shard = SharedCache.getShardForUID(TEntry.Status.getUniqueID()); + return Shard.getOrEmplaceEntryForUID(TEntry.Status.getUniqueID(), + std::move(TEntry.Status), + std::move(TEntry.Contents)); } -llvm::ErrorOr<EntryRef> -DependencyScanningWorkerFilesystem::getOrCreateFileSystemEntry( +const CachedFileSystemEntry * +DependencyScanningWorkerFilesystem::findEntryByFilenameWithWriteThrough( StringRef Filename) { - bool ShouldBeMinimized = shouldMinimize(Filename); - - const auto *Entry = LocalCache.getCachedEntry(Filename); - if (Entry && !Entry->needsUpdate(ShouldBeMinimized)) - return EntryRef(ShouldBeMinimized, *Entry); - - // FIXME: Handle PCM/PCH files. - // FIXME: Handle module map files. - - auto &SharedCacheEntry = SharedCache.get(Filename); - { - std::lock_guard<std::mutex> LockGuard(SharedCacheEntry.ValueLock); - CachedFileSystemEntry &CacheEntry = SharedCacheEntry.Value; - - if (!CacheEntry.isInitialized()) { - auto MaybeStatus = getUnderlyingFS().status(Filename); - if (!MaybeStatus && !shouldCacheStatFailures(Filename)) - // HACK: We need to always restat non source files if the stat fails. - // This is because Clang first looks up the module cache and module - // files before building them, and then looks for them again. If we - // cache the stat failure, it won't see them the second time. - return MaybeStatus.getError(); - CacheEntry.init(std::move(MaybeStatus), Filename, getUnderlyingFS()); - } + if (const auto *Entry = LocalCache.findEntryByFilename(Filename)) + return Entry; + auto &Shard = SharedCache.getShardForFilename(Filename); + if (const auto *Entry = Shard.findEntryByFilename(Filename)) + return &LocalCache.insertEntryForFilename(Filename, *Entry); + return nullptr; +} - // Checking `needsUpdate` verifies the entry represents an opened file. - // Only checking `needsMinimization` could lead to minimization of files - // that we failed to load (such files don't have `OriginalContents`). - if (CacheEntry.needsUpdate(ShouldBeMinimized)) - CacheEntry.minimizeFile(); +llvm::ErrorOr<const CachedFileSystemEntry &> +DependencyScanningWorkerFilesystem::computeAndStoreResult(StringRef Filename) { + llvm::ErrorOr<llvm::vfs::Status> Stat = getUnderlyingFS().status(Filename); + if (!Stat) { + if (!shouldCacheStatFailures(Filename)) + return Stat.getError(); + const auto &Entry = + getOrEmplaceSharedEntryForFilename(Filename, Stat.getError()); + return insertLocalEntryForFilename(Filename, Entry); } - // Store the result in the local cache. - Entry = &SharedCacheEntry.Value; - return EntryRef(ShouldBeMinimized, *Entry); + if (const auto *Entry = findSharedEntryByUID(*Stat)) + return insertLocalEntryForFilename(Filename, *Entry); + + auto TEntry = + Stat->isDirectory() ? TentativeEntry(*Stat) : readFile(Filename); + + const CachedFileSystemEntry *SharedEntry = [&]() { + if (TEntry) { + const auto &UIDEntry = getOrEmplaceSharedEntryForUID(std::move(*TEntry)); + return &getOrInsertSharedEntryForFilename(Filename, UIDEntry); + } + return &getOrEmplaceSharedEntryForFilename(Filename, TEntry.getError()); + }(); + + return insertLocalEntryForFilename(Filename, *SharedEntry); +} + +llvm::ErrorOr<EntryRef> +DependencyScanningWorkerFilesystem::getOrCreateFileSystemEntry( + StringRef Filename, bool DisableMinimization) { + if (const auto *Entry = findEntryByFilenameWithWriteThrough(Filename)) + return minimizeIfNecessary(*Entry, Filename, DisableMinimization) + .unwrapError(); + auto MaybeEntry = computeAndStoreResult(Filename); + if (!MaybeEntry) + return MaybeEntry.getError(); + return minimizeIfNecessary(*MaybeEntry, Filename, DisableMinimization) + .unwrapError(); } llvm::ErrorOr<llvm::vfs::Status> @@ -241,16 +330,16 @@ private: llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>> MinimizedVFSFile::create( EntryRef Entry, ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings) { + assert(!Entry.isError() && "error"); + if (Entry.isDirectory()) return std::make_error_code(std::errc::is_a_directory); - llvm::ErrorOr<StringRef> Contents = Entry.getContents(); - if (!Contents) - return Contents.getError(); auto Result = std::make_unique<MinimizedVFSFile>( - llvm::MemoryBuffer::getMemBuffer(*Contents, Entry.getName(), + llvm::MemoryBuffer::getMemBuffer(Entry.getContents(), + Entry.getStatus().getName(), /*RequiresNullTerminator=*/false), - *Entry.getStatus()); + Entry.getStatus()); const auto *EntrySkipMappings = Entry.getPPSkippedRangeMapping(); if (EntrySkipMappings && !EntrySkipMappings->empty() && PPSkipMappings) diff --git contrib/llvm-project/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp contrib/llvm-project/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp index 29787b8a8894..75d0d50d851f 100644 --- contrib/llvm-project/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp +++ contrib/llvm-project/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp @@ -61,7 +61,7 @@ private: continue; llvm::BumpPtrAllocator Alloc; llvm::StringSaver Saver(Alloc); - llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, + llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, false, llvm::StringRef(Cmd.Directory), *FS); // Don't assign directly, Argv aliases CommandLine. std::vector<std::string> ExpandedArgv(Argv.begin(), Argv.end()); diff --git contrib/llvm-project/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp contrib/llvm-project/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp index c1e25c41f719..51e8439b6b79 100644 --- contrib/llvm-project/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp +++ contrib/llvm-project/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp @@ -243,8 +243,7 @@ struct TransferableCommand { llvm::Twine(ClangCLMode ? "/std:" : "-std=") + LangStandard::getLangStandardForKind(Std).getName()).str()); } - if (Filename.startswith("-") || (ClangCLMode && Filename.startswith("/"))) - Result.CommandLine.push_back("--"); + Result.CommandLine.push_back("--"); Result.CommandLine.push_back(std::string(Filename)); return Result; } diff --git contrib/llvm-project/clang/lib/Tooling/Syntax/Tree.cpp contrib/llvm-project/clang/lib/Tooling/Syntax/Tree.cpp index c813865e95cd..981bac508f73 100644 --- contrib/llvm-project/clang/lib/Tooling/Syntax/Tree.cpp +++ contrib/llvm-project/clang/lib/Tooling/Syntax/Tree.cpp @@ -9,6 +9,7 @@ #include "clang/Basic/TokenKinds.h" #include "clang/Tooling/Syntax/Nodes.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Casting.h" #include <cassert> @@ -202,7 +203,7 @@ static void dumpLeaf(raw_ostream &OS, const syntax::Leaf *L, } static void dumpNode(raw_ostream &OS, const syntax::Node *N, - const SourceManager &SM, std::vector<bool> IndentMask) { + const SourceManager &SM, llvm::BitVector IndentMask) { auto DumpExtraInfo = [&OS](const syntax::Node *N) { if (N->getRole() != syntax::NodeRole::Unknown) OS << " " << N->getRole(); @@ -228,8 +229,8 @@ static void dumpNode(raw_ostream &OS, const syntax::Node *N, OS << "\n"; for (const syntax::Node &It : T->getChildren()) { - for (bool Filled : IndentMask) { - if (Filled) + for (unsigned Idx = 0; Idx < IndentMask.size(); ++Idx) { + if (IndentMask[Idx]) OS << "| "; else OS << " "; diff --git contrib/llvm-project/clang/lib/Tooling/Transformer/Parsing.cpp contrib/llvm-project/clang/lib/Tooling/Transformer/Parsing.cpp index 242db2a16b43..4f41e2e90def 100644 --- contrib/llvm-project/clang/lib/Tooling/Transformer/Parsing.cpp +++ contrib/llvm-project/clang/lib/Tooling/Transformer/Parsing.cpp @@ -33,7 +33,6 @@ using namespace transformer; // much as possible with the AST Matchers parsing. namespace { -using llvm::Error; using llvm::Expected; template <typename... Ts> using RangeSelectorOp = RangeSelector (*)(Ts...); diff --git contrib/llvm-project/clang/lib/Tooling/Transformer/SourceCodeBuilders.cpp contrib/llvm-project/clang/lib/Tooling/Transformer/SourceCodeBuilders.cpp index a1c99b60216b..7496e968469c 100644 --- contrib/llvm-project/clang/lib/Tooling/Transformer/SourceCodeBuilders.cpp +++ contrib/llvm-project/clang/lib/Tooling/Transformer/SourceCodeBuilders.cpp @@ -10,6 +10,8 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Tooling/Transformer/SourceCode.h" #include "llvm/ADT/Twine.h" #include <string> @@ -60,6 +62,16 @@ bool tooling::needParensAfterUnaryOperator(const Expr &E) { return false; } +bool tooling::isKnownPointerLikeType(QualType Ty, ASTContext &Context) { + using namespace ast_matchers; + const auto PointerLikeTy = type(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(cxxRecordDecl(hasAnyName( + "::std::unique_ptr", "::std::shared_ptr", "::std::weak_ptr", + "::std::optional", "::absl::optional", "::llvm::Optional", + "absl::StatusOr", "::llvm::Expected")))))); + return match(PointerLikeTy, Ty, Context).size() > 0; +} + llvm::Optional<std::string> tooling::buildParens(const Expr &E, const ASTContext &Context) { StringRef Text = getText(E, Context); @@ -114,8 +126,10 @@ llvm::Optional<std::string> tooling::buildAddressOf(const Expr &E, return ("&" + Text).str(); } -llvm::Optional<std::string> tooling::buildDot(const Expr &E, - const ASTContext &Context) { +// Append the appropriate access operation (syntactically) to `E`, assuming `E` +// is a non-pointer value. +static llvm::Optional<std::string> +buildAccessForValue(const Expr &E, const ASTContext &Context) { if (const auto *Op = llvm::dyn_cast<UnaryOperator>(&E)) if (Op->getOpcode() == UO_Deref) { // Strip leading '*', add following '->'. @@ -138,8 +152,10 @@ llvm::Optional<std::string> tooling::buildDot(const Expr &E, return (Text + ".").str(); } -llvm::Optional<std::string> tooling::buildArrow(const Expr &E, - const ASTContext &Context) { +// Append the appropriate access operation (syntactically) to `E`, assuming `E` +// is a pointer value. +static llvm::Optional<std::string> +buildAccessForPointer(const Expr &E, const ASTContext &Context) { if (const auto *Op = llvm::dyn_cast<UnaryOperator>(&E)) if (Op->getOpcode() == UO_AddrOf) { // Strip leading '&', add following '.'. @@ -160,3 +176,63 @@ llvm::Optional<std::string> tooling::buildArrow(const Expr &E, return ("(" + Text + ")->").str(); return (Text + "->").str(); } + +llvm::Optional<std::string> tooling::buildDot(const Expr &E, + const ASTContext &Context) { + return buildAccessForValue(E, Context); +} + +llvm::Optional<std::string> tooling::buildArrow(const Expr &E, + const ASTContext &Context) { + return buildAccessForPointer(E, Context); +} + +// If `E` is an overloaded-operator call of kind `K` on an object `O`, returns +// `O`. Otherwise, returns `nullptr`. +static const Expr *maybeGetOperatorObjectArg(const Expr &E, + OverloadedOperatorKind K) { + if (const auto *OpCall = dyn_cast<clang::CXXOperatorCallExpr>(&E)) { + if (OpCall->getOperator() == K && OpCall->getNumArgs() == 1) + return OpCall->getArg(0); + } + return nullptr; +} + +static bool treatLikePointer(QualType Ty, PLTClass C, ASTContext &Context) { + switch (C) { + case PLTClass::Value: + return false; + case PLTClass::Pointer: + return isKnownPointerLikeType(Ty, Context); + } + llvm_unreachable("Unknown PLTClass enum"); +} + +// FIXME: move over the other `maybe` functionality from Stencil. Should all be +// in one place. +llvm::Optional<std::string> tooling::buildAccess(const Expr &RawExpression, + ASTContext &Context, + PLTClass Classification) { + if (RawExpression.isImplicitCXXThis()) + // Return the empty string, because `None` signifies some sort of failure. + return std::string(); + + const Expr *E = RawExpression.IgnoreImplicitAsWritten(); + + if (E->getType()->isAnyPointerType() || + treatLikePointer(E->getType(), Classification, Context)) { + // Strip off operator-> calls. They can only occur inside an actual arrow + // member access, so we treat them as equivalent to an actual object + // expression. + if (const auto *Obj = maybeGetOperatorObjectArg(*E, clang::OO_Arrow)) + E = Obj; + return buildAccessForPointer(*E, Context); + } + + if (const auto *Obj = maybeGetOperatorObjectArg(*E, clang::OO_Star)) { + if (treatLikePointer(Obj->getType(), Classification, Context)) + return buildAccessForPointer(*Obj, Context); + }; + + return buildAccessForValue(*E, Context); +} diff --git contrib/llvm-project/clang/lib/Tooling/Transformer/Stencil.cpp contrib/llvm-project/clang/lib/Tooling/Transformer/Stencil.cpp index 8b20ef34c3ff..348d04dbaf4a 100644 --- contrib/llvm-project/clang/lib/Tooling/Transformer/Stencil.cpp +++ contrib/llvm-project/clang/lib/Tooling/Transformer/Stencil.cpp @@ -11,7 +11,6 @@ #include "clang/AST/ASTTypeTraits.h" #include "clang/AST/Expr.h" #include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Basic/SourceLocation.h" #include "clang/Lex/Lexer.h" #include "clang/Tooling/Transformer/SourceCode.h" @@ -56,39 +55,6 @@ static Error printNode(StringRef Id, const MatchFinder::MatchResult &Match, return Error::success(); } -// FIXME: Consider memoizing this function using the `ASTContext`. -static bool isSmartPointerType(QualType Ty, ASTContext &Context) { - using namespace ::clang::ast_matchers; - - // Optimization: hard-code common smart-pointer types. This can/should be - // removed if we start caching the results of this function. - auto KnownSmartPointer = - cxxRecordDecl(hasAnyName("::std::unique_ptr", "::std::shared_ptr")); - const auto QuacksLikeASmartPointer = cxxRecordDecl( - hasMethod(cxxMethodDecl(hasOverloadedOperatorName("->"), - returns(qualType(pointsTo(type()))))), - hasMethod(cxxMethodDecl(hasOverloadedOperatorName("*"), - returns(qualType(references(type())))))); - const auto SmartPointer = qualType(hasDeclaration( - cxxRecordDecl(anyOf(KnownSmartPointer, QuacksLikeASmartPointer)))); - return match(SmartPointer, Ty, Context).size() > 0; -} - -// Identifies use of `operator*` on smart pointers, and returns the underlying -// smart-pointer expression; otherwise, returns null. -static const Expr *isSmartDereference(const Expr &E, ASTContext &Context) { - using namespace ::clang::ast_matchers; - - const auto HasOverloadedArrow = cxxRecordDecl(hasMethod(cxxMethodDecl( - hasOverloadedOperatorName("->"), returns(qualType(pointsTo(type())))))); - // Verify it is a smart pointer by finding `operator->` in the class - // declaration. - auto Deref = cxxOperatorCallExpr( - hasOverloadedOperatorName("*"), hasUnaryOperand(expr().bind("arg")), - callee(cxxMethodDecl(ofClass(HasOverloadedArrow)))); - return selectFirst<Expr>("arg", match(Deref, E, Context)); -} - namespace { // An arbitrary fragment of code within a stencil. class RawTextStencil : public StencilInterface { @@ -196,7 +162,7 @@ public: break; case UnaryNodeOperator::MaybeDeref: if (E->getType()->isAnyPointerType() || - isSmartPointerType(E->getType(), *Match.Context)) { + tooling::isKnownPointerLikeType(E->getType(), *Match.Context)) { // Strip off any operator->. This can only occur inside an actual arrow // member access, so we treat it as equivalent to an actual object // expression. @@ -216,7 +182,7 @@ public: break; case UnaryNodeOperator::MaybeAddressOf: if (E->getType()->isAnyPointerType() || - isSmartPointerType(E->getType(), *Match.Context)) { + tooling::isKnownPointerLikeType(E->getType(), *Match.Context)) { // Strip off any operator->. This can only occur inside an actual arrow // member access, so we treat it as equivalent to an actual object // expression. @@ -311,34 +277,12 @@ public: if (E == nullptr) return llvm::make_error<StringError>(errc::invalid_argument, "Id not bound: " + BaseId); - if (!E->isImplicitCXXThis()) { - llvm::Optional<std::string> S; - if (E->getType()->isAnyPointerType() || - isSmartPointerType(E->getType(), *Match.Context)) { - // Strip off any operator->. This can only occur inside an actual arrow - // member access, so we treat it as equivalent to an actual object - // expression. - if (const auto *OpCall = dyn_cast<clang::CXXOperatorCallExpr>(E)) { - if (OpCall->getOperator() == clang::OO_Arrow && - OpCall->getNumArgs() == 1) { - E = OpCall->getArg(0); - } - } - S = tooling::buildArrow(*E, *Match.Context); - } else if (const auto *Operand = isSmartDereference(*E, *Match.Context)) { - // `buildDot` already handles the built-in dereference operator, so we - // only need to catch overloaded `operator*`. - S = tooling::buildArrow(*Operand, *Match.Context); - } else { - S = tooling::buildDot(*E, *Match.Context); - } - if (S.hasValue()) - *Result += *S; - else - return llvm::make_error<StringError>( - errc::invalid_argument, - "Could not construct object text from ID: " + BaseId); - } + llvm::Optional<std::string> S = tooling::buildAccess(*E, *Match.Context); + if (!S.hasValue()) + return llvm::make_error<StringError>( + errc::invalid_argument, + "Could not construct object text from ID: " + BaseId); + *Result += *S; return Member->eval(Match, Result); } }; diff --git contrib/llvm-project/clang/tools/driver/cc1_main.cpp contrib/llvm-project/clang/tools/driver/cc1_main.cpp index fd3b25ccb3cb..f648adeba483 100644 --- contrib/llvm-project/clang/tools/driver/cc1_main.cpp +++ contrib/llvm-project/clang/tools/driver/cc1_main.cpp @@ -237,8 +237,10 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) { static_cast<void*>(&Clang->getDiagnostics())); DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics()); - if (!Success) + if (!Success) { + Clang->getDiagnosticClient().finish(); return 1; + } // Execute the frontend actions. { diff --git contrib/llvm-project/clang/tools/driver/cc1as_main.cpp contrib/llvm-project/clang/tools/driver/cc1as_main.cpp index db3288d75281..6459d1534b39 100644 --- contrib/llvm-project/clang/tools/driver/cc1as_main.cpp +++ contrib/llvm-project/clang/tools/driver/cc1as_main.cpp @@ -228,7 +228,6 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, llvm::StringSwitch<llvm::DebugCompressionType>(A->getValue()) .Case("none", llvm::DebugCompressionType::None) .Case("zlib", llvm::DebugCompressionType::Z) - .Case("zlib-gnu", llvm::DebugCompressionType::GNU) .Default(llvm::DebugCompressionType::None); } diff --git contrib/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp contrib/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index 547ec2c82cb3..f4bf4b19911a 100644 --- contrib/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ contrib/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -1311,6 +1311,11 @@ void clang::EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS, else OS << ", false"; + if (R.getValueAsBit("ShowInSystemMacro")) + OS << ", true"; + else + OS << ", false"; + if (R.getValueAsBit("Deferrable")) OS << ", true"; else diff --git contrib/llvm-project/clang/utils/TableGen/MveEmitter.cpp contrib/llvm-project/clang/utils/TableGen/MveEmitter.cpp index 1a2532fbf53f..cc830c1d5416 100644 --- contrib/llvm-project/clang/utils/TableGen/MveEmitter.cpp +++ contrib/llvm-project/clang/utils/TableGen/MveEmitter.cpp @@ -1489,8 +1489,7 @@ protected: class raw_self_contained_string_ostream : private string_holder, public raw_string_ostream { public: - raw_self_contained_string_ostream() - : string_holder(), raw_string_ostream(S) {} + raw_self_contained_string_ostream() : raw_string_ostream(S) {} }; const char LLVMLicenseHeader[] = diff --git contrib/llvm-project/clang/utils/TableGen/NeonEmitter.cpp contrib/llvm-project/clang/utils/TableGen/NeonEmitter.cpp index ff552b66c0e2..a69fbe0e42dc 100644 --- contrib/llvm-project/clang/utils/TableGen/NeonEmitter.cpp +++ contrib/llvm-project/clang/utils/TableGen/NeonEmitter.cpp @@ -292,7 +292,7 @@ class Variable { std::string N; public: - Variable() : T(Type::getVoid()), N("") {} + Variable() : T(Type::getVoid()) {} Variable(Type T, std::string N) : T(std::move(T)), N(std::move(N)) {} Type getType() const { return T; } @@ -1306,7 +1306,7 @@ void Intrinsic::emitBodyAsBuiltinCall() { if (LocalCK == ClassB) { Type T2 = T; T2.makeOneVector(); - T2.makeInteger(8, /*Signed=*/true); + T2.makeInteger(8, /*Sign=*/true); Cast = "(" + T2.str() + ")"; } @@ -1473,7 +1473,7 @@ Intrinsic::DagEmitter::emitDagCall(DagInit *DI, bool MatchMangledName) { Intr.Dependencies.insert(&Callee); // Now create the call itself. - std::string S = ""; + std::string S; if (!Callee.isBigEndianSafe()) S += CallPrefix.str(); S += Callee.getMangledName(true) + "("; diff --git contrib/llvm-project/clang/utils/TableGen/RISCVVEmitter.cpp contrib/llvm-project/clang/utils/TableGen/RISCVVEmitter.cpp index 62eef830318f..4b80d6da72fa 100644 --- contrib/llvm-project/clang/utils/TableGen/RISCVVEmitter.cpp +++ contrib/llvm-project/clang/utils/TableGen/RISCVVEmitter.cpp @@ -100,6 +100,9 @@ public: bool isValid() const { return Valid; } bool isScalar() const { return Scale.hasValue() && Scale.getValue() == 0; } bool isVector() const { return Scale.hasValue() && Scale.getValue() != 0; } + bool isVector(unsigned Width) const { + return isVector() && ElementBitwidth == Width; + } bool isFloat() const { return ScalarType == ScalarTypeKind::Float; } bool isSignedInteger() const { return ScalarType == ScalarTypeKind::SignedInteger; @@ -134,13 +137,16 @@ private: using RVVTypePtr = RVVType *; using RVVTypes = std::vector<RVVTypePtr>; +using RISCVPredefinedMacroT = uint8_t; -enum RISCVExtension : uint8_t { +enum RISCVPredefinedMacro : RISCVPredefinedMacroT { Basic = 0, - F = 1 << 1, - D = 1 << 2, - Zfh = 1 << 3, - Zvlsseg = 1 << 4, + V = 1 << 1, + Zfh = 1 << 2, + RV64 = 1 << 3, + VectorMaxELen64 = 1 << 4, + VectorMaxELenFp32 = 1 << 5, + VectorMaxELenFp64 = 1 << 6, }; // TODO refactor RVVIntrinsic class design after support all intrinsic @@ -164,7 +170,7 @@ private: // The types we use to obtain the specific LLVM intrinsic. They are index of // InputTypes. -1 means the return type. std::vector<int64_t> IntrinsicTypes; - uint8_t RISCVExtensions = 0; + RISCVPredefinedMacroT RISCVPredefinedMacros = 0; unsigned NF = 1; public: @@ -174,7 +180,7 @@ public: bool HasNoMaskedOverloaded, bool HasAutoDef, StringRef ManualCodegen, const RVVTypes &Types, const std::vector<int64_t> &IntrinsicTypes, - StringRef RequiredExtension, unsigned NF); + const std::vector<StringRef> &RequiredFeatures, unsigned NF); ~RVVIntrinsic() = default; StringRef getBuiltinName() const { return BuiltinName; } @@ -188,7 +194,9 @@ public: bool isMask() const { return IsMask; } StringRef getIRName() const { return IRName; } StringRef getManualCodegen() const { return ManualCodegen; } - uint8_t getRISCVExtensions() const { return RISCVExtensions; } + RISCVPredefinedMacroT getRISCVPredefinedMacros() const { + return RISCVPredefinedMacros; + } unsigned getNF() const { return NF; } const std::vector<int64_t> &getIntrinsicTypes() const { return IntrinsicTypes; @@ -251,7 +259,8 @@ private: // Emit the architecture preprocessor definitions. Return true when emits // non-empty string. - bool emitExtDefStr(uint8_t Extensions, raw_ostream &o); + bool emitMacroRestrictionStr(RISCVPredefinedMacroT PredefinedMacros, + raw_ostream &o); // Slice Prototypes string into sub prototype string and process each sub // prototype string individually in the Handler. void parsePrototypes(StringRef Prototypes, @@ -444,8 +453,8 @@ void RVVType::initBuiltinStr() { return; } BuiltinStr = "q" + utostr(Scale.getValue()) + BuiltinStr; - // Pointer to vector types. Defined for Zvlsseg load intrinsics. - // Zvlsseg load intrinsics have pointer type arguments to store the loaded + // Pointer to vector types. Defined for segment load intrinsics. + // segment load intrinsics have pointer type arguments to store the loaded // vector values. if (IsPointer) BuiltinStr += "*"; @@ -764,7 +773,8 @@ RVVIntrinsic::RVVIntrinsic(StringRef NewName, StringRef Suffix, bool HasNoMaskedOverloaded, bool HasAutoDef, StringRef ManualCodegen, const RVVTypes &OutInTypes, const std::vector<int64_t> &NewIntrinsicTypes, - StringRef RequiredExtension, unsigned NF) + const std::vector<StringRef> &RequiredFeatures, + unsigned NF) : IRName(IRName), IsMask(IsMask), HasVL(HasVL), HasPolicy(HasPolicy), HasNoMaskedOverloaded(HasNoMaskedOverloaded), HasAutoDef(HasAutoDef), ManualCodegen(ManualCodegen.str()), NF(NF) { @@ -788,14 +798,23 @@ RVVIntrinsic::RVVIntrinsic(StringRef NewName, StringRef Suffix, // Init RISC-V extensions for (const auto &T : OutInTypes) { if (T->isFloatVector(16) || T->isFloat(16)) - RISCVExtensions |= RISCVExtension::Zfh; - else if (T->isFloatVector(32) || T->isFloat(32)) - RISCVExtensions |= RISCVExtension::F; - else if (T->isFloatVector(64) || T->isFloat(64)) - RISCVExtensions |= RISCVExtension::D; + RISCVPredefinedMacros |= RISCVPredefinedMacro::Zfh; + if (T->isFloatVector(32)) + RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELenFp32; + if (T->isFloatVector(64)) + RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELenFp64; + if (T->isVector(64)) + RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELen64; + } + for (auto Feature : RequiredFeatures) { + if (Feature == "RV64") + RISCVPredefinedMacros |= RISCVPredefinedMacro::RV64; + // Note: Full multiply instruction (mulh, mulhu, mulhsu, smul) for EEW=64 + // require V. + if (Feature == "FullMultiply" && + (RISCVPredefinedMacros & RISCVPredefinedMacro::VectorMaxELen64)) + RISCVPredefinedMacros |= RISCVPredefinedMacro::V; } - if (RequiredExtension == "Zvlsseg") - RISCVExtensions |= RISCVExtension::Zvlsseg; // Init OutputType and InputTypes OutputType = OutInTypes[0]; @@ -978,7 +997,7 @@ void RVVEmitter::createHeader(raw_ostream &OS) { // The same extension include in the same arch guard marco. llvm::stable_sort(Defs, [](const std::unique_ptr<RVVIntrinsic> &A, const std::unique_ptr<RVVIntrinsic> &B) { - return A->getRISCVExtensions() < B->getRISCVExtensions(); + return A->getRISCVPredefinedMacros() < B->getRISCVPredefinedMacros(); }); OS << "#define __rvv_ai static __inline__\n"; @@ -1021,7 +1040,7 @@ void RVVEmitter::createBuiltins(raw_ostream &OS) { OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN)\n"; OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, " - "ATTRS, \"experimental-v\")\n"; + "ATTRS, \"zve32x|v\")\n"; OS << "#endif\n"; for (auto &Def : Defs) { auto P = @@ -1141,7 +1160,8 @@ void RVVEmitter::createRVVIntrinsics( StringRef ManualCodegenMask = R->getValueAsString("ManualCodegenMask"); std::vector<int64_t> IntrinsicTypes = R->getValueAsListOfInts("IntrinsicTypes"); - StringRef RequiredExtension = R->getValueAsString("RequiredExtension"); + std::vector<StringRef> RequiredFeatures = + R->getValueAsListOfStrings("RequiredFeatures"); StringRef IRName = R->getValueAsString("IRName"); StringRef IRNameMask = R->getValueAsString("IRNameMask"); unsigned NF = R->getValueAsInt("NF"); @@ -1209,7 +1229,7 @@ void RVVEmitter::createRVVIntrinsics( Name, SuffixStr, MangledName, MangledSuffixStr, IRName, /*IsMask=*/false, /*HasMaskedOffOperand=*/false, HasVL, HasPolicy, HasNoMaskedOverloaded, HasAutoDef, ManualCodegen, Types.getValue(), - IntrinsicTypes, RequiredExtension, NF)); + IntrinsicTypes, RequiredFeatures, NF)); if (HasMask) { // Create a mask intrinsic Optional<RVVTypes> MaskTypes = @@ -1218,7 +1238,7 @@ void RVVEmitter::createRVVIntrinsics( Name, SuffixStr, MangledName, MangledSuffixStr, IRNameMask, /*IsMask=*/true, HasMaskedOffOperand, HasVL, HasPolicy, HasNoMaskedOverloaded, HasAutoDef, ManualCodegenMask, - MaskTypes.getValue(), IntrinsicTypes, RequiredExtension, NF)); + MaskTypes.getValue(), IntrinsicTypes, RequiredFeatures, NF)); } } // end for Log2LMULList } // end for TypeRange @@ -1276,15 +1296,16 @@ Optional<RVVTypePtr> RVVEmitter::computeType(BasicType BT, int Log2LMUL, void RVVEmitter::emitArchMacroAndBody( std::vector<std::unique_ptr<RVVIntrinsic>> &Defs, raw_ostream &OS, std::function<void(raw_ostream &, const RVVIntrinsic &)> PrintBody) { - uint8_t PrevExt = (*Defs.begin())->getRISCVExtensions(); - bool NeedEndif = emitExtDefStr(PrevExt, OS); + RISCVPredefinedMacroT PrevMacros = + (*Defs.begin())->getRISCVPredefinedMacros(); + bool NeedEndif = emitMacroRestrictionStr(PrevMacros, OS); for (auto &Def : Defs) { - uint8_t CurExt = Def->getRISCVExtensions(); - if (CurExt != PrevExt) { + RISCVPredefinedMacroT CurMacros = Def->getRISCVPredefinedMacros(); + if (CurMacros != PrevMacros) { if (NeedEndif) OS << "#endif\n\n"; - NeedEndif = emitExtDefStr(CurExt, OS); - PrevExt = CurExt; + NeedEndif = emitMacroRestrictionStr(CurMacros, OS); + PrevMacros = CurMacros; } if (Def->hasAutoDef()) PrintBody(OS, *Def); @@ -1293,19 +1314,24 @@ void RVVEmitter::emitArchMacroAndBody( OS << "#endif\n\n"; } -bool RVVEmitter::emitExtDefStr(uint8_t Extents, raw_ostream &OS) { - if (Extents == RISCVExtension::Basic) +bool RVVEmitter::emitMacroRestrictionStr(RISCVPredefinedMacroT PredefinedMacros, + raw_ostream &OS) { + if (PredefinedMacros == RISCVPredefinedMacro::Basic) return false; OS << "#if "; ListSeparator LS(" && "); - if (Extents & RISCVExtension::F) - OS << LS << "defined(__riscv_f)"; - if (Extents & RISCVExtension::D) - OS << LS << "defined(__riscv_d)"; - if (Extents & RISCVExtension::Zfh) + if (PredefinedMacros & RISCVPredefinedMacro::V) + OS << LS << "defined(__riscv_v)"; + if (PredefinedMacros & RISCVPredefinedMacro::Zfh) OS << LS << "defined(__riscv_zfh)"; - if (Extents & RISCVExtension::Zvlsseg) - OS << LS << "defined(__riscv_zvlsseg)"; + if (PredefinedMacros & RISCVPredefinedMacro::RV64) + OS << LS << "(__riscv_xlen == 64)"; + if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELen64) + OS << LS << "(__riscv_v_elen >= 64)"; + if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELenFp32) + OS << LS << "(__riscv_v_elen_fp >= 32)"; + if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELenFp64) + OS << LS << "(__riscv_v_elen_fp >= 64)"; OS << "\n"; return true; } diff --git contrib/llvm-project/compiler-rt/include/profile/InstrProfData.inc contrib/llvm-project/compiler-rt/include/profile/InstrProfData.inc index 44719126b596..0544b6b2ef71 100644 --- contrib/llvm-project/compiler-rt/include/profile/InstrProfData.inc +++ contrib/llvm-project/compiler-rt/include/profile/InstrProfData.inc @@ -128,8 +128,10 @@ INSTR_PROF_VALUE_NODE(PtrToNodeT, llvm::Type::getInt8PtrTy(Ctx), Next, \ INSTR_PROF_RAW_HEADER(uint64_t, Magic, __llvm_profile_get_magic()) INSTR_PROF_RAW_HEADER(uint64_t, Version, __llvm_profile_get_version()) INSTR_PROF_RAW_HEADER(uint64_t, BinaryIdsSize, __llvm_write_binary_ids(NULL)) +/* FIXME: A more accurate name is NumData */ INSTR_PROF_RAW_HEADER(uint64_t, DataSize, DataSize) INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesBeforeCounters, PaddingBytesBeforeCounters) +/* FIXME: A more accurate name is NumCounters */ INSTR_PROF_RAW_HEADER(uint64_t, CountersSize, CountersSize) INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesAfterCounters, PaddingBytesAfterCounters) INSTR_PROF_RAW_HEADER(uint64_t, NamesSize, NamesSize) @@ -644,6 +646,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | (uint64_t)'o' << 24 | \ (uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129 +/* FIXME: Please remedy the fixme in the header before bumping the version. */ /* Raw profile format version (start from 1). */ #define INSTR_PROF_RAW_VERSION 8 /* Indexed profile format version (start from 1). */ diff --git contrib/llvm-project/compiler-rt/include/sanitizer/dfsan_interface.h contrib/llvm-project/compiler-rt/include/sanitizer/dfsan_interface.h index bc0652c99a14..8e581a67572d 100644 --- contrib/llvm-project/compiler-rt/include/sanitizer/dfsan_interface.h +++ contrib/llvm-project/compiler-rt/include/sanitizer/dfsan_interface.h @@ -27,6 +27,10 @@ typedef uint32_t dfsan_origin; /// Signature of the callback argument to dfsan_set_write_callback(). typedef void (*dfsan_write_callback_t)(int fd, const void *buf, size_t count); +/// Signature of the callback argument to dfsan_set_conditional_callback(). +typedef void (*dfsan_conditional_callback_t)(dfsan_label label, + dfsan_origin origin); + /// Computes the union of \c l1 and \c l2, resulting in a union label. dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2); @@ -74,6 +78,19 @@ void dfsan_flush(void); /// callback executes. Pass in NULL to remove any callback. void dfsan_set_write_callback(dfsan_write_callback_t labeled_write_callback); +/// Sets a callback to be invoked on any conditional expressions which have a +/// taint label set. This can be used to find where tainted data influences +/// the behavior of the program. +/// These callbacks will only be added when -dfsan-conditional-callbacks=true. +void dfsan_set_conditional_callback(dfsan_conditional_callback_t callback); + +/// Conditional expressions occur during signal handlers. +/// Making callbacks that handle signals well is tricky, so when +/// -dfsan-conditional-callbacks=true, conditional expressions used in signal +/// handlers will add the labels they see into a global (bitwise-or together). +/// This function returns all label bits seen in signal handler conditions. +dfsan_label dfsan_get_labels_in_signal_conditional(); + /// Interceptor hooks. /// Whenever a dfsan's custom function is called the corresponding /// hook is called it non-zero. The hooks should be defined by the user. diff --git contrib/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp contrib/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp index 1ff7091460ad..f9f1cfcd9f87 100644 --- contrib/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp +++ contrib/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp @@ -840,12 +840,12 @@ struct Allocator { quarantine.PrintStats(); } - void ForceLock() ACQUIRE(fallback_mutex) { + void ForceLock() SANITIZER_ACQUIRE(fallback_mutex) { allocator.ForceLock(); fallback_mutex.Lock(); } - void ForceUnlock() RELEASE(fallback_mutex) { + void ForceUnlock() SANITIZER_RELEASE(fallback_mutex) { fallback_mutex.Unlock(); allocator.ForceUnlock(); } @@ -1054,9 +1054,11 @@ uptr asan_mz_size(const void *ptr) { return instance.AllocationSize(reinterpret_cast<uptr>(ptr)); } -void asan_mz_force_lock() NO_THREAD_SAFETY_ANALYSIS { instance.ForceLock(); } +void asan_mz_force_lock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { + instance.ForceLock(); +} -void asan_mz_force_unlock() NO_THREAD_SAFETY_ANALYSIS { +void asan_mz_force_unlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { instance.ForceUnlock(); } diff --git contrib/llvm-project/compiler-rt/lib/asan/asan_mapping.h contrib/llvm-project/compiler-rt/lib/asan/asan_mapping.h index 6ca6ee00e5c9..4ff09b103d5f 100644 --- contrib/llvm-project/compiler-rt/lib/asan/asan_mapping.h +++ contrib/llvm-project/compiler-rt/lib/asan/asan_mapping.h @@ -13,6 +13,8 @@ #ifndef ASAN_MAPPING_H #define ASAN_MAPPING_H +#include "sanitizer_common/sanitizer_platform.h" + // The full explanation of the memory mapping could be found here: // https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm // diff --git contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_static.cpp contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_static.cpp new file mode 100644 index 000000000000..74e6eb0ddf1c --- /dev/null +++ contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_static.cpp @@ -0,0 +1,15 @@ +//===-- asan_static_rtl.cpp -----------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Main file of the ASan run-time library. +//===----------------------------------------------------------------------===// + +// This file is empty for now. Main reason to have it is workaround for Windows +// build, which complains because no files are part of the asan_static lib. diff --git contrib/llvm-project/compiler-rt/lib/asan/asan_win_dll_thunk.cpp contrib/llvm-project/compiler-rt/lib/asan/asan_win_dll_thunk.cpp index a5671cc9dffd..e3a90f18ed81 100644 --- contrib/llvm-project/compiler-rt/lib/asan/asan_win_dll_thunk.cpp +++ contrib/llvm-project/compiler-rt/lib/asan/asan_win_dll_thunk.cpp @@ -56,6 +56,13 @@ INTERCEPT_WRAP_W_W(_expand_dbg) // TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cpp) +# if defined(_MSC_VER) && !defined(__clang__) +// Disable warnings such as: 'void memchr(void)': incorrect number of arguments +// for intrinsic function, expected '3' arguments. +# pragma warning(push) +# pragma warning(disable : 4392) +# endif + INTERCEPT_LIBRARY_FUNCTION(atoi); INTERCEPT_LIBRARY_FUNCTION(atol); INTERCEPT_LIBRARY_FUNCTION(frexp); @@ -87,6 +94,10 @@ INTERCEPT_LIBRARY_FUNCTION(strtol); INTERCEPT_LIBRARY_FUNCTION(wcslen); INTERCEPT_LIBRARY_FUNCTION(wcsnlen); +# if defined(_MSC_VER) && !defined(__clang__) +# pragma warning(pop) +# endif + #ifdef _WIN64 INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler); #else diff --git contrib/llvm-project/compiler-rt/lib/builtins/assembly.h contrib/llvm-project/compiler-rt/lib/builtins/assembly.h index 9c015059af5a..69a3d8620f92 100644 --- contrib/llvm-project/compiler-rt/lib/builtins/assembly.h +++ contrib/llvm-project/compiler-rt/lib/builtins/assembly.h @@ -14,6 +14,12 @@ #ifndef COMPILERRT_ASSEMBLY_H #define COMPILERRT_ASSEMBLY_H +#if defined(__linux__) && defined(__CET__) +#if __has_include(<cet.h>) +#include <cet.h> +#endif +#endif + #if defined(__APPLE__) && defined(__aarch64__) #define SEPARATOR %% #else diff --git contrib/llvm-project/compiler-rt/lib/builtins/cpu_model.c contrib/llvm-project/compiler-rt/lib/builtins/cpu_model.c index cf12aa021d3d..aa0fd7d85b57 100644 --- contrib/llvm-project/compiler-rt/lib/builtins/cpu_model.c +++ contrib/llvm-project/compiler-rt/lib/builtins/cpu_model.c @@ -13,6 +13,10 @@ // //===----------------------------------------------------------------------===// +#ifndef __has_attribute +#define __has_attribute(attr) 0 +#endif + #if defined(HAVE_INIT_PRIORITY) #define CONSTRUCTOR_ATTRIBUTE __attribute__((__constructor__ 101)) #elif __has_attribute(__constructor__) @@ -37,10 +41,6 @@ #include <intrin.h> #endif -#ifndef __has_attribute -#define __has_attribute(attr) 0 -#endif - enum VendorSignatures { SIG_INTEL = 0x756e6547, // Genu SIG_AMD = 0x68747541, // Auth diff --git contrib/llvm-project/compiler-rt/lib/builtins/emutls.c contrib/llvm-project/compiler-rt/lib/builtins/emutls.c index e112fdf51440..3a2908a42484 100644 --- contrib/llvm-project/compiler-rt/lib/builtins/emutls.c +++ contrib/llvm-project/compiler-rt/lib/builtins/emutls.c @@ -30,7 +30,7 @@ // MSVC raises a warning about a nonstandard extension being used for the 0 // sized element in this array. Disable this for warn-as-error builds. #pragma warning(push) -#pragma warning(disable : 4206) +#pragma warning(disable : 4200) #endif typedef struct emutls_address_array { diff --git contrib/llvm-project/compiler-rt/lib/builtins/fp_mode.h contrib/llvm-project/compiler-rt/lib/builtins/fp_mode.h index 26a3f4d10942..5b4969a441f2 100644 --- contrib/llvm-project/compiler-rt/lib/builtins/fp_mode.h +++ contrib/llvm-project/compiler-rt/lib/builtins/fp_mode.h @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef FP_MODE -#define FP_MODE +#ifndef FP_MODE_H +#define FP_MODE_H typedef enum { CRT_FE_TONEAREST, diff --git contrib/llvm-project/compiler-rt/lib/builtins/udivmoddi4.c contrib/llvm-project/compiler-rt/lib/builtins/udivmoddi4.c index 10b41df28f84..ca17b36ce585 100644 --- contrib/llvm-project/compiler-rt/lib/builtins/udivmoddi4.c +++ contrib/llvm-project/compiler-rt/lib/builtins/udivmoddi4.c @@ -21,7 +21,7 @@ // MSVC throws a warning about mod 0 here, disable it for builds that // warn-as-error #pragma warning(push) -#pragma warning(disable : 4724) +#pragma warning(disable : 4723 4724) #endif COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem) { diff --git contrib/llvm-project/compiler-rt/lib/cfi/cfi.cpp contrib/llvm-project/compiler-rt/lib/cfi/cfi.cpp index 65a10c999cc6..22f0b175dd87 100644 --- contrib/llvm-project/compiler-rt/lib/cfi/cfi.cpp +++ contrib/llvm-project/compiler-rt/lib/cfi/cfi.cpp @@ -322,14 +322,14 @@ void InitShadow() { THREADLOCAL int in_loader; Mutex shadow_update_lock; -void EnterLoader() NO_THREAD_SAFETY_ANALYSIS { +void EnterLoader() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { if (in_loader == 0) { shadow_update_lock.Lock(); } ++in_loader; } -void ExitLoader() NO_THREAD_SAFETY_ANALYSIS { +void ExitLoader() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { CHECK(in_loader > 0); --in_loader; UpdateShadow(); diff --git contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.cpp contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.cpp index ee7221c7b9a8..afb01c7d889e 100644 --- contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.cpp +++ contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.cpp @@ -332,9 +332,9 @@ static void MoveOrigin(const void *dst, const void *src, uptr size, // origins by copying origins in a reverse order; otherwise, copy origins in // a normal order. The orders of origin transfer are consistent with the // orders of how memcpy and memmove transfer user data. - uptr src_aligned_beg = reinterpret_cast<uptr>(src) & ~3UL; - uptr src_aligned_end = (reinterpret_cast<uptr>(src) + size) & ~3UL; - uptr dst_aligned_beg = reinterpret_cast<uptr>(dst) & ~3UL; + uptr src_aligned_beg = OriginAlignDown((uptr)src); + uptr src_aligned_end = OriginAlignDown((uptr)src + size); + uptr dst_aligned_beg = OriginAlignDown((uptr)dst); if (dst_aligned_beg < src_aligned_end && dst_aligned_beg >= src_aligned_beg) return ReverseCopyOrigin(dst, src, size, stack); return CopyOrigin(dst, src, size, stack); @@ -401,12 +401,18 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_mem_origin_transfer( MoveOrigin(dst, src, len, &stack); } -SANITIZER_INTERFACE_ATTRIBUTE void dfsan_mem_origin_transfer(const void *dst, - const void *src, - uptr len) { +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void dfsan_mem_origin_transfer( + const void *dst, const void *src, uptr len) { __dfsan_mem_origin_transfer(dst, src, len); } +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void dfsan_mem_shadow_transfer( + void *dst, const void *src, uptr len) { + internal_memcpy((void *)__dfsan::shadow_for(dst), + (const void *)__dfsan::shadow_for(src), + len * sizeof(dfsan_label)); +} + namespace __dfsan { bool dfsan_inited = false; @@ -414,8 +420,7 @@ bool dfsan_init_is_running = false; void dfsan_copy_memory(void *dst, const void *src, uptr size) { internal_memcpy(dst, src, size); - internal_memcpy((void *)shadow_for(dst), (const void *)shadow_for(src), - size * sizeof(dfsan_label)); + dfsan_mem_shadow_transfer(dst, src, size); if (dfsan_get_track_origins()) dfsan_mem_origin_transfer(dst, src, size); } @@ -600,6 +605,60 @@ dfsan_has_label(dfsan_label label, dfsan_label elem) { return (label & elem) == elem; } +namespace __dfsan { + +typedef void (*dfsan_conditional_callback_t)(dfsan_label label, + dfsan_origin origin); +static dfsan_conditional_callback_t conditional_callback = nullptr; +static dfsan_label labels_in_signal_conditional = 0; + +static void ConditionalCallback(dfsan_label label, dfsan_origin origin) { + // Programs have many branches. For efficiency the conditional sink callback + // handler needs to ignore as many as possible as early as possible. + if (label == 0) { + return; + } + if (conditional_callback == nullptr) { + return; + } + + // This initial ConditionalCallback handler needs to be in here in dfsan + // runtime (rather than being an entirely user implemented hook) so that it + // has access to dfsan thread information. + DFsanThread *t = GetCurrentThread(); + // A callback operation which does useful work (like record the flow) will + // likely be too long executed in a signal handler. + if (t && t->InSignalHandler()) { + // Record set of labels used in signal handler for completeness. + labels_in_signal_conditional |= label; + return; + } + + conditional_callback(label, origin); +} + +} // namespace __dfsan + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void +__dfsan_conditional_callback_origin(dfsan_label label, dfsan_origin origin) { + __dfsan::ConditionalCallback(label, origin); +} + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_conditional_callback( + dfsan_label label) { + __dfsan::ConditionalCallback(label, 0); +} + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void dfsan_set_conditional_callback( + __dfsan::dfsan_conditional_callback_t callback) { + __dfsan::conditional_callback = callback; +} + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label +dfsan_get_labels_in_signal_conditional() { + return __dfsan::labels_in_signal_conditional; +} + class Decorator : public __sanitizer::SanitizerCommonDecorator { public: Decorator() : SanitizerCommonDecorator() {} @@ -898,6 +957,7 @@ extern "C" void dfsan_flush() { Die(); } } + __dfsan::labels_in_signal_conditional = 0; } // TODO: CheckMemoryLayoutSanity is based on msan. diff --git contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.h contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.h index b529e008f300..f3403dd44fa8 100644 --- contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.h +++ contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.h @@ -46,6 +46,10 @@ void dfsan_set_label_origin(dfsan_label label, dfsan_origin origin, void *addr, // Copy or move the origins of the len bytes from src to dst. void dfsan_mem_origin_transfer(const void *dst, const void *src, uptr len); + +// Copy shadow bytes from src to dst. +// Note this preserves distinct taint labels at specific offsets. +void dfsan_mem_shadow_transfer(void *dst, const void *src, uptr len); } // extern "C" template <typename T> diff --git contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_custom.cpp contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_custom.cpp index 217bd35c1c54..1965d0ddff59 100644 --- contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_custom.cpp +++ contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_custom.cpp @@ -497,9 +497,7 @@ static void *dfsan_memmove_with_origin(void *dest, const void *src, size_t n) { } static void *dfsan_memcpy(void *dest, const void *src, size_t n) { - dfsan_label *sdest = shadow_for(dest); - const dfsan_label *ssrc = shadow_for(src); - internal_memcpy((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label)); + dfsan_mem_shadow_transfer(dest, src, n); return internal_memcpy(dest, src, n); } @@ -584,10 +582,7 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src, dfsan_label *ret_label) { size_t dest_len = strlen(dest); char *ret = strcat(dest, src); - dfsan_label *sdest = shadow_for(dest + dest_len); - const dfsan_label *ssrc = shadow_for(src); - internal_memcpy((void *)sdest, (const void *)ssrc, - strlen(src) * sizeof(dfsan_label)); + dfsan_mem_shadow_transfer(dest + dest_len, src, strlen(src)); *ret_label = dest_label; return ret; } @@ -598,12 +593,9 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strcat( dfsan_origin *ret_origin) { size_t dest_len = strlen(dest); char *ret = strcat(dest, src); - dfsan_label *sdest = shadow_for(dest + dest_len); - const dfsan_label *ssrc = shadow_for(src); size_t src_len = strlen(src); dfsan_mem_origin_transfer(dest + dest_len, src, src_len); - internal_memcpy((void *)sdest, (const void *)ssrc, - src_len * sizeof(dfsan_label)); + dfsan_mem_shadow_transfer(dest + dest_len, src, src_len); *ret_label = dest_label; *ret_origin = dest_origin; return ret; @@ -1120,8 +1112,7 @@ char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label, dfsan_label src_label, dfsan_label *ret_label) { char *ret = strcpy(dest, src); if (ret) { - internal_memcpy(shadow_for(dest), shadow_for(src), - sizeof(dfsan_label) * (strlen(src) + 1)); + dfsan_mem_shadow_transfer(dest, src, strlen(src) + 1); } *ret_label = dst_label; return ret; @@ -1136,8 +1127,7 @@ char *__dfso_strcpy(char *dest, const char *src, dfsan_label dst_label, if (ret) { size_t str_len = strlen(src) + 1; dfsan_mem_origin_transfer(dest, src, str_len); - internal_memcpy(shadow_for(dest), shadow_for(src), - sizeof(dfsan_label) * str_len); + dfsan_mem_shadow_transfer(dest, src, str_len); } *ret_label = dst_label; *ret_origin = dst_origin; @@ -2369,9 +2359,8 @@ static int format_buffer(char *str, size_t size, const char *fmt, formatter.num_written_bytes(retval)); } va_labels++; - internal_memcpy(shadow_for(formatter.str_cur()), shadow_for(arg), - sizeof(dfsan_label) * - formatter.num_written_bytes(retval)); + dfsan_mem_shadow_transfer(formatter.str_cur(), arg, + formatter.num_written_bytes(retval)); end_fmt = true; break; } diff --git contrib/llvm-project/compiler-rt/lib/dfsan/done_abilist.txt contrib/llvm-project/compiler-rt/lib/dfsan/done_abilist.txt index fc2dd02ccf5f..e8fcd83d13bf 100644 --- contrib/llvm-project/compiler-rt/lib/dfsan/done_abilist.txt +++ contrib/llvm-project/compiler-rt/lib/dfsan/done_abilist.txt @@ -46,6 +46,10 @@ fun:dfsan_get_init_origin=uninstrumented fun:dfsan_get_init_origin=discard fun:dfsan_get_track_origins=uninstrumented fun:dfsan_get_track_origins=discard +fun:dfsan_set_conditional_callback=uninstrumented +fun:dfsan_set_conditional_callback=discard +fun:dfsan_get_labels_in_signal_conditional=uninstrumented +fun:dfsan_get_labels_in_signal_conditional=discard ############################################################################### # glibc diff --git contrib/llvm-project/compiler-rt/lib/interception/interception_win.cpp contrib/llvm-project/compiler-rt/lib/interception/interception_win.cpp index 38b8c058246a..9289e06b88fc 100644 --- contrib/llvm-project/compiler-rt/lib/interception/interception_win.cpp +++ contrib/llvm-project/compiler-rt/lib/interception/interception_win.cpp @@ -602,6 +602,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0x246c8948: // 48 89 6C 24 XX : mov QWORD ptr [rsp + XX], rbp case 0x245c8948: // 48 89 5c 24 XX : mov QWORD PTR [rsp + XX], rbx case 0x24748948: // 48 89 74 24 XX : mov QWORD PTR [rsp + XX], rsi + case 0x247c8948: // 48 89 7c 24 XX : mov QWORD PTR [rsp + XX], rdi case 0x244C8948: // 48 89 4C 24 XX : mov QWORD PTR [rsp + XX], rcx case 0x24548948: // 48 89 54 24 XX : mov QWORD PTR [rsp + XX], rdx case 0x244c894c: // 4c 89 4c 24 XX : mov QWORD PTR [rsp + XX], r9 diff --git contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.h contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.h index 61b64d4dc30f..6b06c4517cd5 100644 --- contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.h +++ contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.h @@ -230,8 +230,8 @@ void UnlockAllocator(); // Returns true if [addr, addr + sizeof(void *)) is poisoned. bool WordIsPoisoned(uptr addr); // Wrappers for ThreadRegistry access. -void LockThreadRegistry() NO_THREAD_SAFETY_ANALYSIS; -void UnlockThreadRegistry() NO_THREAD_SAFETY_ANALYSIS; +void LockThreadRegistry() SANITIZER_NO_THREAD_SAFETY_ANALYSIS; +void UnlockThreadRegistry() SANITIZER_NO_THREAD_SAFETY_ANALYSIS; struct ScopedStopTheWorldLock { ScopedStopTheWorldLock() { diff --git contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_mac.cpp contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_mac.cpp index 6e8a6dfe16b4..a4204740c7fa 100644 --- contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_mac.cpp +++ contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_mac.cpp @@ -143,16 +143,16 @@ void ProcessGlobalRegions(Frontier *frontier) { } void ProcessPlatformSpecificAllocations(Frontier *frontier) { - unsigned depth = 1; - vm_size_t size = 0; vm_address_t address = 0; kern_return_t err = KERN_SUCCESS; - mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; InternalMmapVectorNoCtor<RootRegion> const *root_regions = GetRootRegions(); while (err == KERN_SUCCESS) { + vm_size_t size = 0; + unsigned depth = 1; struct vm_region_submap_info_64 info; + mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; err = vm_region_recurse_64(mach_task_self(), &address, &size, &depth, (vm_region_info_t)&info, &count); diff --git contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp index adbdf365bc4c..0974b898666b 100644 --- contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp +++ contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp @@ -524,12 +524,12 @@ struct Allocator { void PrintStats() { allocator.PrintStats(); } - void ForceLock() NO_THREAD_SAFETY_ANALYSIS { + void ForceLock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { allocator.ForceLock(); fallback_mutex.Lock(); } - void ForceUnlock() NO_THREAD_SAFETY_ANALYSIS { + void ForceUnlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { fallback_mutex.Unlock(); allocator.ForceUnlock(); } diff --git contrib/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp contrib/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp index df0cdecf79c7..d1b858930a7f 100644 --- contrib/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp +++ contrib/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp @@ -990,12 +990,13 @@ static void SignalAction(int signo, void *si, void *uc) { ScopedThreadLocalStateBackup stlsb; UnpoisonParam(3); __msan_unpoison(si, sizeof(__sanitizer_sigaction)); - __msan_unpoison(uc, __sanitizer::ucontext_t_sz); + __msan_unpoison(uc, ucontext_t_sz(uc)); typedef void (*sigaction_cb)(int, void *, void *); sigaction_cb cb = (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed); cb(signo, si, uc); + CHECK_UNPOISONED(uc, ucontext_t_sz(uc)); } static void read_sigaction(const __sanitizer_sigaction *act) { diff --git contrib/llvm-project/compiler-rt/lib/orc/adt.h contrib/llvm-project/compiler-rt/lib/orc/adt.h index 33b731082f88..3a422871c47b 100644 --- contrib/llvm-project/compiler-rt/lib/orc/adt.h +++ contrib/llvm-project/compiler-rt/lib/orc/adt.h @@ -110,4 +110,4 @@ inline std::string to_string(string_view SV) { } // end namespace __orc_rt -#endif // ORC_RT_COMMON_H +#endif // ORC_RT_ADT_H diff --git contrib/llvm-project/compiler-rt/lib/orc/debug.cpp contrib/llvm-project/compiler-rt/lib/orc/debug.cpp new file mode 100644 index 000000000000..af20fa4e6f4e --- /dev/null +++ contrib/llvm-project/compiler-rt/lib/orc/debug.cpp @@ -0,0 +1,83 @@ +//===- debug.cpp ----------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file is a part of the ORC runtime support library. +// +//===----------------------------------------------------------------------===// + +#include "debug.h" + +#include <cassert> +#include <cstdarg> +#include <cstdio> +#include <cstdlib> +#include <cstring> + + +namespace __orc_rt { + +#ifndef NDEBUG + +std::atomic<const char *> DebugTypes; +char DebugTypesAll; +char DebugTypesNone; + +/// Sets the DebugState and DebugTypes values -- this function may be called +/// concurrently on multiple threads, but will always assign the same values so +/// this should be safe. +const char *initializeDebug() { + if (const char *DT = getenv("ORC_RT_DEBUG")) { + // If ORC_RT_DEBUG=1 then log everything. + if (strcmp(DT, "1") == 0) { + DebugTypes.store(&DebugTypesAll, std::memory_order_relaxed); + return &DebugTypesAll; + } + + // If ORC_RT_DEBUG is non-empty then record the string for use in + // debugTypeEnabled. + if (strcmp(DT, "") != 0) { + DebugTypes.store(DT, std::memory_order_relaxed); + return DT; + } + } + + // If ORT_RT_DEBUG is undefined or defined as empty then log nothing. + DebugTypes.store(&DebugTypesNone, std::memory_order_relaxed); + return &DebugTypesNone; +} + +bool debugTypeEnabled(const char *Type, const char *Types) { + assert(Types && Types != &DebugTypesAll && Types != &DebugTypesNone && + "Invalid Types value"); + size_t TypeLen = strlen(Type); + const char *Start = Types; + const char *End = Start; + + do { + if (*End == '\0' || *End == ',') { + size_t ItemLen = End - Start; + if (ItemLen == TypeLen && memcmp(Type, Start, TypeLen) == 0) + return true; + if (*End == '\0') + return false; + Start = End + 1; + } + ++End; + } while (true); +} + +void printdbg(const char *format, ...) { + va_list Args; + va_start(Args, format); + vfprintf(stderr, format, Args); + va_end(Args); +} + +#endif // !NDEBUG + +} // end namespace __orc_rt diff --git contrib/llvm-project/compiler-rt/lib/orc/debug.h contrib/llvm-project/compiler-rt/lib/orc/debug.h new file mode 100644 index 000000000000..4605d441c7cb --- /dev/null +++ contrib/llvm-project/compiler-rt/lib/orc/debug.h @@ -0,0 +1,56 @@ +//===- debug.h - Debugging output utilities ---------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file is a part of the ORC runtime support library. +// +//===----------------------------------------------------------------------===// + +#ifndef ORC_RT_DEBUG_H +#define ORC_RT_DEBUG_H + +#include <atomic> + +#ifndef NDEBUG + +namespace __orc_rt { + +extern std::atomic<const char *> DebugTypes; +extern char DebugTypesAll; +extern char DebugTypesNone; + +const char *initializeDebug(); +bool debugTypeEnabled(const char *Type, const char *Types); +void printdbg(const char *format, ...); + +} // namespace __orc_rt + +#define ORC_RT_DEBUG_WITH_TYPE(TYPE, X) \ + do { \ + const char *Types = \ + ::__orc_rt::DebugTypes.load(std::memory_order_relaxed); \ + if (!Types) \ + Types = initializeDebug(); \ + if (Types == &DebugTypesNone) \ + break; \ + if (Types == &DebugTypesAll || \ + ::__orc_rt::debugTypeEnabled(TYPE, Types)) { \ + X; \ + } \ + } while (false) + +#else + +#define ORC_RT_DEBUG_WITH_TYPE(TYPE, X) \ + do { \ + } while (false) + +#endif // !NDEBUG + +#define ORC_RT_DEBUG(X) ORC_RT_DEBUG_WITH_TYPE(DEBUG_TYPE, X) + +#endif // ORC_RT_COMMON_H diff --git contrib/llvm-project/compiler-rt/lib/orc/macho_ehframe_registration.cpp contrib/llvm-project/compiler-rt/lib/orc/macho_ehframe_registration.cpp index d0ea7e70201c..f077cea96820 100644 --- contrib/llvm-project/compiler-rt/lib/orc/macho_ehframe_registration.cpp +++ contrib/llvm-project/compiler-rt/lib/orc/macho_ehframe_registration.cpp @@ -13,6 +13,8 @@ #include "adt.h" #include "c_api.h" #include "common.h" +#include "executor_address.h" +#include "wrapper_function_utils.h" using namespace __orc_rt; @@ -49,20 +51,24 @@ void walkEHFrameSection(span<const char> EHFrameSection, ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult __orc_rt_macho_register_ehframe_section(char *ArgData, size_t ArgSize) { - // NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer - // is taken to be the range of the eh-frame section. - bool HasError = false; - walkEHFrameSection(span<const char>(ArgData, ArgSize), __register_frame); - return __orc_rt_CreateCWrapperFunctionResultFromRange((char*)&HasError, - sizeof(HasError)); + return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle( + ArgData, ArgSize, + [](ExecutorAddrRange FrameSection) -> Error { + walkEHFrameSection(FrameSection.toSpan<const char>(), + __register_frame); + return Error::success(); + }) + .release(); } ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult __orc_rt_macho_deregister_ehframe_section(char *ArgData, size_t ArgSize) { - // NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer - // is taken to be the range of the eh-frame section. - bool HasError = false; - walkEHFrameSection(span<const char>(ArgData, ArgSize), __deregister_frame); - return __orc_rt_CreateCWrapperFunctionResultFromRange((char*)&HasError, - sizeof(HasError)); + return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle( + ArgData, ArgSize, + [](ExecutorAddrRange FrameSection) -> Error { + walkEHFrameSection(FrameSection.toSpan<const char>(), + __deregister_frame); + return Error::success(); + }) + .release(); } diff --git contrib/llvm-project/compiler-rt/lib/orc/macho_platform.cpp contrib/llvm-project/compiler-rt/lib/orc/macho_platform.cpp index 32770219e65c..f2cca8eb829a 100644 --- contrib/llvm-project/compiler-rt/lib/orc/macho_platform.cpp +++ contrib/llvm-project/compiler-rt/lib/orc/macho_platform.cpp @@ -568,7 +568,7 @@ void destroyMachOTLVMgr(void *MachOTLVMgr) { Error runWrapperFunctionCalls(std::vector<WrapperFunctionCall> WFCs) { for (auto &WFC : WFCs) - if (auto Err = WFC.runWithSPSRet()) + if (auto Err = WFC.runWithSPSRet<void>()) return Err; return Error::success(); } @@ -593,28 +593,22 @@ __orc_rt_macho_platform_shutdown(char *ArgData, size_t ArgSize) { ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult __orc_rt_macho_register_thread_data_section(char *ArgData, size_t ArgSize) { - // NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer - // is taken to be the range of the thread data section. - return WrapperFunction<SPSError()>::handle( - nullptr, 0, - [&]() { + return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle( + ArgData, ArgSize, + [](ExecutorAddrRange R) { return MachOPlatformRuntimeState::get() - .registerThreadDataSection( - span<const char>(ArgData, ArgSize)); + .registerThreadDataSection(R.toSpan<const char>()); }) .release(); } ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult __orc_rt_macho_deregister_thread_data_section(char *ArgData, size_t ArgSize) { - // NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer - // is taken to be the range of the thread data section. - return WrapperFunction<SPSError()>::handle( - nullptr, 0, - [&]() { + return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle( + ArgData, ArgSize, + [](ExecutorAddrRange R) { return MachOPlatformRuntimeState::get() - .deregisterThreadDataSection( - span<const char>(ArgData, ArgSize)); + .deregisterThreadDataSection(R.toSpan<const char>()); }) .release(); } diff --git contrib/llvm-project/compiler-rt/lib/orc/wrapper_function_utils.h contrib/llvm-project/compiler-rt/lib/orc/wrapper_function_utils.h index 23385e1bd794..02ea37393276 100644 --- contrib/llvm-project/compiler-rt/lib/orc/wrapper_function_utils.h +++ contrib/llvm-project/compiler-rt/lib/orc/wrapper_function_utils.h @@ -395,25 +395,53 @@ makeMethodWrapperHandler(RetT (ClassT::*Method)(ArgTs...)) { } /// Represents a call to a wrapper function. -struct WrapperFunctionCall { - ExecutorAddr Func; - ExecutorAddrRange ArgData; +class WrapperFunctionCall { +public: + // FIXME: Switch to a SmallVector<char, 24> once ORC runtime has a + // smallvector. + using ArgDataBufferType = std::vector<char>; + + /// Create a WrapperFunctionCall using the given SPS serializer to serialize + /// the arguments. + template <typename SPSSerializer, typename... ArgTs> + static Expected<WrapperFunctionCall> Create(ExecutorAddr FnAddr, + const ArgTs &...Args) { + ArgDataBufferType ArgData; + ArgData.resize(SPSSerializer::size(Args...)); + SPSOutputBuffer OB(&ArgData[0], ArgData.size()); + if (SPSSerializer::serialize(OB, Args...)) + return WrapperFunctionCall(FnAddr, std::move(ArgData)); + return make_error<StringError>("Cannot serialize arguments for " + "AllocActionCall"); + } WrapperFunctionCall() = default; - WrapperFunctionCall(ExecutorAddr Func, ExecutorAddrRange ArgData) - : Func(Func), ArgData(ArgData) {} - /// Run and return result as WrapperFunctionResult. - WrapperFunctionResult run() { - WrapperFunctionResult WFR( - Func.toPtr<__orc_rt_CWrapperFunctionResult (*)(const char *, size_t)>()( - ArgData.Start.toPtr<const char *>(), - static_cast<size_t>(ArgData.size().getValue()))); - return WFR; + /// Create a WrapperFunctionCall from a target function and arg buffer. + WrapperFunctionCall(ExecutorAddr FnAddr, ArgDataBufferType ArgData) + : FnAddr(FnAddr), ArgData(std::move(ArgData)) {} + + /// Returns the address to be called. + const ExecutorAddr &getCallee() const { return FnAddr; } + + /// Returns the argument data. + const ArgDataBufferType &getArgData() const { return ArgData; } + + /// WrapperFunctionCalls convert to true if the callee is non-null. + explicit operator bool() const { return !!FnAddr; } + + /// Run call returning raw WrapperFunctionResult. + WrapperFunctionResult run() const { + using FnTy = + __orc_rt_CWrapperFunctionResult(const char *ArgData, size_t ArgSize); + return WrapperFunctionResult( + FnAddr.toPtr<FnTy *>()(ArgData.data(), ArgData.size())); } /// Run call and deserialize result using SPS. - template <typename SPSRetT, typename RetT> Error runWithSPSRet(RetT &RetVal) { + template <typename SPSRetT, typename RetT> + std::enable_if_t<!std::is_same<SPSRetT, void>::value, Error> + runWithSPSRet(RetT &RetVal) const { auto WFR = run(); if (const char *ErrMsg = WFR.getOutOfBandError()) return make_error<StringError>(ErrMsg); @@ -425,30 +453,49 @@ struct WrapperFunctionCall { } /// Overload for SPS functions returning void. - Error runWithSPSRet() { + template <typename SPSRetT> + std::enable_if_t<std::is_same<SPSRetT, void>::value, Error> + runWithSPSRet() const { SPSEmpty E; return runWithSPSRet<SPSEmpty>(E); } + + /// Run call and deserialize an SPSError result. SPSError returns and + /// deserialization failures are merged into the returned error. + Error runWithSPSRetErrorMerged() const { + detail::SPSSerializableError RetErr; + if (auto Err = runWithSPSRet<SPSError>(RetErr)) + return Err; + return detail::fromSPSSerializable(std::move(RetErr)); + } + +private: + ExecutorAddr FnAddr; + std::vector<char> ArgData; }; -class SPSWrapperFunctionCall {}; +using SPSWrapperFunctionCall = SPSTuple<SPSExecutorAddr, SPSSequence<char>>; template <> class SPSSerializationTraits<SPSWrapperFunctionCall, WrapperFunctionCall> { public: static size_t size(const WrapperFunctionCall &WFC) { - return SPSArgList<SPSExecutorAddr, SPSExecutorAddrRange>::size(WFC.Func, - WFC.ArgData); + return SPSArgList<SPSExecutorAddr, SPSSequence<char>>::size( + WFC.getCallee(), WFC.getArgData()); } static bool serialize(SPSOutputBuffer &OB, const WrapperFunctionCall &WFC) { - return SPSArgList<SPSExecutorAddr, SPSExecutorAddrRange>::serialize( - OB, WFC.Func, WFC.ArgData); + return SPSArgList<SPSExecutorAddr, SPSSequence<char>>::serialize( + OB, WFC.getCallee(), WFC.getArgData()); } static bool deserialize(SPSInputBuffer &IB, WrapperFunctionCall &WFC) { - return SPSArgList<SPSExecutorAddr, SPSExecutorAddrRange>::deserialize( - IB, WFC.Func, WFC.ArgData); + ExecutorAddr FnAddr; + WrapperFunctionCall::ArgDataBufferType ArgData; + if (!SPSWrapperFunctionCall::AsArgList::deserialize(IB, FnAddr, ArgData)) + return false; + WFC = WrapperFunctionCall(FnAddr, std::move(ArgData)); + return true; } }; diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.c contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.c index 7c1d357d96fe..557c0da2dbae 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.c +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.c @@ -42,10 +42,10 @@ COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_version(void) { } COMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) { - uint64_t *I = __llvm_profile_begin_counters(); - uint64_t *E = __llvm_profile_end_counters(); + char *I = __llvm_profile_begin_counters(); + char *E = __llvm_profile_end_counters(); - memset(I, 0, sizeof(uint64_t) * (E - I)); + memset(I, 0, E - I); const __llvm_profile_data *DataBegin = __llvm_profile_begin_data(); const __llvm_profile_data *DataEnd = __llvm_profile_end_data(); diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.h contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.h index 5b88d7178012..4433d7bd4887 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.h +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.h @@ -86,8 +86,8 @@ const __llvm_profile_data *__llvm_profile_begin_data(void); const __llvm_profile_data *__llvm_profile_end_data(void); const char *__llvm_profile_begin_names(void); const char *__llvm_profile_end_names(void); -uint64_t *__llvm_profile_begin_counters(void); -uint64_t *__llvm_profile_end_counters(void); +char *__llvm_profile_begin_counters(void); +char *__llvm_profile_end_counters(void); ValueProfNode *__llvm_profile_begin_vnodes(); ValueProfNode *__llvm_profile_end_vnodes(); uint32_t *__llvm_profile_begin_orderfile(); @@ -260,17 +260,26 @@ uint64_t __llvm_profile_get_magic(void); uint64_t __llvm_profile_get_version(void); /*! \brief Get the number of entries in the profile data section. */ +uint64_t __llvm_profile_get_num_data(const __llvm_profile_data *Begin, + const __llvm_profile_data *End); + +/*! \brief Get the size of the profile data section in bytes. */ uint64_t __llvm_profile_get_data_size(const __llvm_profile_data *Begin, const __llvm_profile_data *End); +/*! \brief Get the size in bytes of a single counter entry. */ +size_t __llvm_profile_counter_entry_size(void); + +/*! \brief Get the number of entries in the profile counters section. */ +uint64_t __llvm_profile_get_num_counters(const char *Begin, const char *End); + +/*! \brief Get the size of the profile counters section in bytes. */ +uint64_t __llvm_profile_get_counters_size(const char *Begin, const char *End); + /* ! \brief Given the sizes of the data and counter information, return the * number of padding bytes before and after the counters, and after the names, * in the raw profile. * - * Note: In this context, "size" means "number of entries", i.e. the first two - * arguments must be the result of __llvm_profile_get_data_size() and of - * (__llvm_profile_end_counters() - __llvm_profile_begin_counters()) resp. - * * Note: When mmap() mode is disabled, no padding bytes before/after counters * are needed. However, in mmap() mode, the counter section in the raw profile * must be page-aligned: this API computes the number of padding bytes diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingBuffer.c contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingBuffer.c index 68b4f5cd6f52..f3d15511452e 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingBuffer.c +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingBuffer.c @@ -41,8 +41,8 @@ COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_size_for_buffer(void) { const __llvm_profile_data *DataBegin = __llvm_profile_begin_data(); const __llvm_profile_data *DataEnd = __llvm_profile_end_data(); - const uint64_t *CountersBegin = __llvm_profile_begin_counters(); - const uint64_t *CountersEnd = __llvm_profile_end_counters(); + const char *CountersBegin = __llvm_profile_begin_counters(); + const char *CountersEnd = __llvm_profile_end_counters(); const char *NamesBegin = __llvm_profile_begin_names(); const char *NamesEnd = __llvm_profile_end_names(); @@ -51,13 +51,36 @@ uint64_t __llvm_profile_get_size_for_buffer(void) { } COMPILER_RT_VISIBILITY -uint64_t __llvm_profile_get_data_size(const __llvm_profile_data *Begin, - const __llvm_profile_data *End) { +uint64_t __llvm_profile_get_num_data(const __llvm_profile_data *Begin, + const __llvm_profile_data *End) { intptr_t BeginI = (intptr_t)Begin, EndI = (intptr_t)End; return ((EndI + sizeof(__llvm_profile_data) - 1) - BeginI) / sizeof(__llvm_profile_data); } +COMPILER_RT_VISIBILITY +uint64_t __llvm_profile_get_data_size(const __llvm_profile_data *Begin, + const __llvm_profile_data *End) { + return __llvm_profile_get_num_data(Begin, End) * sizeof(__llvm_profile_data); +} + +COMPILER_RT_VISIBILITY size_t __llvm_profile_counter_entry_size(void) { + return sizeof(uint64_t); +} + +COMPILER_RT_VISIBILITY +uint64_t __llvm_profile_get_num_counters(const char *Begin, const char *End) { + intptr_t BeginI = (intptr_t)Begin, EndI = (intptr_t)End; + return ((EndI + __llvm_profile_counter_entry_size() - 1) - BeginI) / + __llvm_profile_counter_entry_size(); +} + +COMPILER_RT_VISIBILITY +uint64_t __llvm_profile_get_counters_size(const char *Begin, const char *End) { + return __llvm_profile_get_num_counters(Begin, End) * + __llvm_profile_counter_entry_size(); +} + /// Calculate the number of padding bytes needed to add to \p Offset in order /// for (\p Offset + Padding) to be page-aligned. static uint64_t calculateBytesNeededToPageAlign(uint64_t Offset) { @@ -89,24 +112,22 @@ void __llvm_profile_get_padding_sizes_for_counters( // In continuous mode, the file offsets for headers and for the start of // counter sections need to be page-aligned. - uint64_t DataSizeInBytes = DataSize * sizeof(__llvm_profile_data); - uint64_t CountersSizeInBytes = CountersSize * sizeof(uint64_t); - *PaddingBytesBeforeCounters = calculateBytesNeededToPageAlign( - sizeof(__llvm_profile_header) + DataSizeInBytes); - *PaddingBytesAfterCounters = - calculateBytesNeededToPageAlign(CountersSizeInBytes); + *PaddingBytesBeforeCounters = + calculateBytesNeededToPageAlign(sizeof(__llvm_profile_header) + DataSize); + *PaddingBytesAfterCounters = calculateBytesNeededToPageAlign(CountersSize); *PaddingBytesAfterNames = calculateBytesNeededToPageAlign(NamesSize); } COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_size_for_buffer_internal( const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, - const uint64_t *CountersBegin, const uint64_t *CountersEnd, - const char *NamesBegin, const char *NamesEnd) { + const char *CountersBegin, const char *CountersEnd, const char *NamesBegin, + const char *NamesEnd) { /* Match logic in __llvm_profile_write_buffer(). */ const uint64_t NamesSize = (NamesEnd - NamesBegin) * sizeof(char); uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd); - uint64_t CountersSize = CountersEnd - CountersBegin; + uint64_t CountersSize = + __llvm_profile_get_counters_size(CountersBegin, CountersEnd); /* Determine how much padding is needed before/after the counters and after * the names. */ @@ -117,9 +138,8 @@ uint64_t __llvm_profile_get_size_for_buffer_internal( &PaddingBytesAfterCounters, &PaddingBytesAfterNames); return sizeof(__llvm_profile_header) + __llvm_write_binary_ids(NULL) + - (DataSize * sizeof(__llvm_profile_data)) + PaddingBytesBeforeCounters + - (CountersSize * sizeof(uint64_t)) + PaddingBytesAfterCounters + - NamesSize + PaddingBytesAfterNames; + DataSize + PaddingBytesBeforeCounters + CountersSize + + PaddingBytesAfterCounters + NamesSize + PaddingBytesAfterNames; } COMPILER_RT_VISIBILITY @@ -136,8 +156,8 @@ COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer(char *Buffer) { COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer_internal( char *Buffer, const __llvm_profile_data *DataBegin, - const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin, - const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd) { + const __llvm_profile_data *DataEnd, const char *CountersBegin, + const char *CountersEnd, const char *NamesBegin, const char *NamesEnd) { ProfDataWriter BufferWriter; initBufferWriter(&BufferWriter, Buffer); return lprofWriteDataImpl(&BufferWriter, DataBegin, DataEnd, CountersBegin, diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c index efd9f06ac6ee..363ded9554ce 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c @@ -106,13 +106,14 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) { * __llvm_profile_get_size_for_buffer(). */ const __llvm_profile_data *DataBegin = __llvm_profile_begin_data(); const __llvm_profile_data *DataEnd = __llvm_profile_end_data(); - const uint64_t *CountersBegin = __llvm_profile_begin_counters(); - const uint64_t *CountersEnd = __llvm_profile_end_counters(); + const char *CountersBegin = __llvm_profile_begin_counters(); + const char *CountersEnd = __llvm_profile_end_counters(); const char *NamesBegin = __llvm_profile_begin_names(); const char *NamesEnd = __llvm_profile_end_names(); const uint64_t NamesSize = (NamesEnd - NamesBegin) * sizeof(char); uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd); - uint64_t CountersSize = CountersEnd - CountersBegin; + uint64_t CountersSize = + __llvm_profile_get_counters_size(CountersBegin, CountersEnd); /* Check that the counter and data sections in this image are * page-aligned. */ @@ -136,11 +137,10 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) { DataSize, CountersSize, NamesSize, &PaddingBytesBeforeCounters, &PaddingBytesAfterCounters, &PaddingBytesAfterNames); - uint64_t PageAlignedCountersLength = - (CountersSize * sizeof(uint64_t)) + PaddingBytesAfterCounters; - uint64_t FileOffsetToCounters = - CurrentFileOffset + sizeof(__llvm_profile_header) + - (DataSize * sizeof(__llvm_profile_data)) + PaddingBytesBeforeCounters; + uint64_t PageAlignedCountersLength = CountersSize + PaddingBytesAfterCounters; + uint64_t FileOffsetToCounters = CurrentFileOffset + + sizeof(__llvm_profile_header) + DataSize + + PaddingBytesBeforeCounters; uint64_t *CounterMmap = (uint64_t *)mmap( (void *)CountersBegin, PageAlignedCountersLength, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, Fileno, FileOffsetToCounters); @@ -195,8 +195,8 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) { * __llvm_profile_get_size_for_buffer(). */ const __llvm_profile_data *DataBegin = __llvm_profile_begin_data(); const __llvm_profile_data *DataEnd = __llvm_profile_end_data(); - const uint64_t *CountersBegin = __llvm_profile_begin_counters(); - const uint64_t *CountersEnd = __llvm_profile_end_counters(); + const char *CountersBegin = __llvm_profile_begin_counters(); + const char *CountersEnd = __llvm_profile_end_counters(); uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd); /* Get the file size. */ uint64_t FileSize = 0; @@ -211,8 +211,7 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) { return 1; } const uint64_t CountersOffsetInBiasMode = - sizeof(__llvm_profile_header) + __llvm_write_binary_ids(NULL) + - (DataSize * sizeof(__llvm_profile_data)); + sizeof(__llvm_profile_header) + __llvm_write_binary_ids(NULL) + DataSize; /* Update the profile fields based on the current mapping. */ INSTR_PROF_PROFILE_COUNTER_BIAS_VAR = (intptr_t)Profile - (uintptr_t)CountersBegin + CountersOffsetInBiasMode; @@ -578,9 +577,8 @@ static void initializeProfileForContinuousMode(void) { } /* Get the sizes of counter section. */ - const uint64_t *CountersBegin = __llvm_profile_begin_counters(); - const uint64_t *CountersEnd = __llvm_profile_end_counters(); - uint64_t CountersSize = CountersEnd - CountersBegin; + uint64_t CountersSize = __llvm_profile_get_counters_size( + __llvm_profile_begin_counters(), __llvm_profile_end_counters()); int Length = getCurFilenameLength(); char *FilenameBuf = (char *)COMPILER_RT_ALLOCA(Length + 1); diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingInternal.h contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingInternal.h index 1394ea8c42f8..b2ce11067abd 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingInternal.h +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingInternal.h @@ -21,8 +21,8 @@ */ uint64_t __llvm_profile_get_size_for_buffer_internal( const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, - const uint64_t *CountersBegin, const uint64_t *CountersEnd, - const char *NamesBegin, const char *NamesEnd); + const char *CountersBegin, const char *CountersEnd, const char *NamesBegin, + const char *NamesEnd); /*! * \brief Write instrumentation data to the given buffer, given explicit @@ -35,8 +35,8 @@ uint64_t __llvm_profile_get_size_for_buffer_internal( */ int __llvm_profile_write_buffer_internal( char *Buffer, const __llvm_profile_data *DataBegin, - const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin, - const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd); + const __llvm_profile_data *DataEnd, const char *CountersBegin, + const char *CountersEnd, const char *NamesBegin, const char *NamesEnd); /*! * The data structure describing the data to be written by the @@ -152,8 +152,7 @@ int lprofWriteData(ProfDataWriter *Writer, VPDataReaderType *VPDataReader, int lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, - const uint64_t *CountersBegin, - const uint64_t *CountersEnd, + const char *CountersBegin, const char *CountersEnd, VPDataReaderType *VPDataReader, const char *NamesBegin, const char *NamesEnd, int SkipNameDataWrite); diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c index bf99521d4da7..3a520f1488a7 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c @@ -23,18 +23,18 @@ COMPILER_RT_VISIBILITY uint64_t lprofGetLoadModuleSignature() { /* A very fast way to compute a module signature. */ uint64_t Version = __llvm_profile_get_version(); - uint64_t CounterSize = (uint64_t)(__llvm_profile_end_counters() - - __llvm_profile_begin_counters()); - uint64_t DataSize = __llvm_profile_get_data_size(__llvm_profile_begin_data(), - __llvm_profile_end_data()); + uint64_t NumCounters = __llvm_profile_get_num_counters( + __llvm_profile_begin_counters(), __llvm_profile_end_counters()); + uint64_t NumData = __llvm_profile_get_num_data(__llvm_profile_begin_data(), + __llvm_profile_end_data()); uint64_t NamesSize = (uint64_t)(__llvm_profile_end_names() - __llvm_profile_begin_names()); uint64_t NumVnodes = (uint64_t)(__llvm_profile_end_vnodes() - __llvm_profile_begin_vnodes()); const __llvm_profile_data *FirstD = __llvm_profile_begin_data(); - return (NamesSize << 40) + (CounterSize << 30) + (DataSize << 20) + - (NumVnodes << 10) + (DataSize > 0 ? FirstD->NameRef : 0) + Version + + return (NamesSize << 40) + (NumCounters << 30) + (NumData << 20) + + (NumVnodes << 10) + (NumData > 0 ? FirstD->NameRef : 0) + Version + __llvm_profile_get_magic(); } @@ -57,18 +57,20 @@ int __llvm_profile_check_compatibility(const char *ProfileData, if (Header->Magic != __llvm_profile_get_magic() || Header->Version != __llvm_profile_get_version() || Header->DataSize != - __llvm_profile_get_data_size(__llvm_profile_begin_data(), - __llvm_profile_end_data()) || - Header->CountersSize != (uint64_t)(__llvm_profile_end_counters() - - __llvm_profile_begin_counters()) || + __llvm_profile_get_num_data(__llvm_profile_begin_data(), + __llvm_profile_end_data()) || + Header->CountersSize != + __llvm_profile_get_num_counters(__llvm_profile_begin_counters(), + __llvm_profile_end_counters()) || Header->NamesSize != (uint64_t)(__llvm_profile_end_names() - __llvm_profile_begin_names()) || Header->ValueKindLast != IPVK_Last) return 1; - if (ProfileSize < sizeof(__llvm_profile_header) + Header->BinaryIdsSize + - Header->DataSize * sizeof(__llvm_profile_data) + - Header->NamesSize + Header->CountersSize) + if (ProfileSize < + sizeof(__llvm_profile_header) + Header->BinaryIdsSize + + Header->DataSize * sizeof(__llvm_profile_data) + Header->NamesSize + + Header->CountersSize * __llvm_profile_counter_entry_size()) return 1; for (SrcData = SrcDataStart, @@ -105,7 +107,7 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, __llvm_profile_data *SrcDataStart, *SrcDataEnd, *SrcData, *DstData; __llvm_profile_header *Header = (__llvm_profile_header *)ProfileData; - uint64_t *SrcCountersStart; + char *SrcCountersStart; const char *SrcNameStart; const char *SrcValueProfDataStart, *SrcValueProfData; uintptr_t CountersDelta = Header->CountersDelta; @@ -114,12 +116,13 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, (__llvm_profile_data *)(ProfileData + sizeof(__llvm_profile_header) + Header->BinaryIdsSize); SrcDataEnd = SrcDataStart + Header->DataSize; - SrcCountersStart = (uint64_t *)SrcDataEnd; - SrcNameStart = (const char *)(SrcCountersStart + Header->CountersSize); + SrcCountersStart = (char *)SrcDataEnd; + SrcNameStart = SrcCountersStart + + Header->CountersSize * __llvm_profile_counter_entry_size(); SrcValueProfDataStart = SrcNameStart + Header->NamesSize + __llvm_profile_get_num_padding_bytes(Header->NamesSize); - if (SrcNameStart < (const char *)SrcCountersStart) + if (SrcNameStart < SrcCountersStart) return 1; for (SrcData = SrcDataStart, @@ -130,8 +133,8 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, // address of the data to the start address of the counter. On WIN64, // CounterPtr is a truncated 32-bit value due to COFF limitation. Sign // extend CounterPtr to get the original value. - uint64_t *DstCounters = - (uint64_t *)((uintptr_t)DstData + signextIfWin64(DstData->CounterPtr)); + char *DstCounters = + (char *)((uintptr_t)DstData + signextIfWin64(DstData->CounterPtr)); unsigned NVK = 0; // SrcData is a serialized representation of the memory image. We need to @@ -141,21 +144,19 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, // CountersDelta computes the offset into the in-buffer counter section. // // On WIN64, CountersDelta is truncated as well, so no need for signext. - uint64_t *SrcCounters = - SrcCountersStart + - ((uintptr_t)SrcData->CounterPtr - CountersDelta) / sizeof(uint64_t); + char *SrcCounters = + SrcCountersStart + ((uintptr_t)SrcData->CounterPtr - CountersDelta); // CountersDelta needs to be decreased as we advance to the next data // record. CountersDelta -= sizeof(*SrcData); unsigned NC = SrcData->NumCounters; if (NC == 0) return 1; - if (SrcCounters < SrcCountersStart || - (const char *)SrcCounters >= SrcNameStart || - (const char *)(SrcCounters + NC) > SrcNameStart) + if (SrcCounters < SrcCountersStart || SrcCounters >= SrcNameStart || + (SrcCounters + __llvm_profile_counter_entry_size() * NC) > SrcNameStart) return 1; for (unsigned I = 0; I < NC; I++) - DstCounters[I] += SrcCounters[I]; + ((uint64_t *)DstCounters)[I] += ((uint64_t *)SrcCounters)[I]; /* Now merge value profile data. */ if (!VPMergeHook) diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c index c2e7fad98386..d9f2a113f5b0 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c @@ -26,11 +26,10 @@ extern char COMPILER_RT_VISIBILITY extern char NamesEnd __asm("section$end$__DATA$" INSTR_PROF_NAME_SECT_NAME); COMPILER_RT_VISIBILITY -extern uint64_t +extern char CountersStart __asm("section$start$__DATA$" INSTR_PROF_CNTS_SECT_NAME); COMPILER_RT_VISIBILITY -extern uint64_t - CountersEnd __asm("section$end$__DATA$" INSTR_PROF_CNTS_SECT_NAME); +extern char CountersEnd __asm("section$end$__DATA$" INSTR_PROF_CNTS_SECT_NAME); COMPILER_RT_VISIBILITY extern uint32_t OrderFileStart __asm("section$start$__DATA$" INSTR_PROF_ORDERFILE_SECT_NAME); @@ -53,9 +52,9 @@ const char *__llvm_profile_begin_names(void) { return &NamesStart; } COMPILER_RT_VISIBILITY const char *__llvm_profile_end_names(void) { return &NamesEnd; } COMPILER_RT_VISIBILITY -uint64_t *__llvm_profile_begin_counters(void) { return &CountersStart; } +char *__llvm_profile_begin_counters(void) { return &CountersStart; } COMPILER_RT_VISIBILITY -uint64_t *__llvm_profile_end_counters(void) { return &CountersEnd; } +char *__llvm_profile_end_counters(void) { return &CountersEnd; } COMPILER_RT_VISIBILITY uint32_t *__llvm_profile_begin_orderfile(void) { return &OrderFileStart; } diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c index 9bea795e8e3a..ee2bd56b4b53 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c @@ -116,13 +116,13 @@ void __llvm_profile_initialize(void) { const __llvm_profile_data *DataBegin = __llvm_profile_begin_data(); const __llvm_profile_data *DataEnd = __llvm_profile_end_data(); - const uint64_t *CountersBegin = __llvm_profile_begin_counters(); - const uint64_t *CountersEnd = __llvm_profile_end_counters(); + const char *CountersBegin = __llvm_profile_begin_counters(); + const char *CountersEnd = __llvm_profile_end_counters(); const uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd); const uint64_t CountersOffset = - sizeof(__llvm_profile_header) + __llvm_write_binary_ids(NULL) + - (DataSize * sizeof(__llvm_profile_data)); - uint64_t CountersSize = CountersEnd - CountersBegin; + sizeof(__llvm_profile_header) + __llvm_write_binary_ids(NULL) + DataSize; + uint64_t CountersSize = + __llvm_profile_get_counters_size(CountersBegin, CountersEnd); /* Don't publish a VMO if there are no counters. */ if (!CountersSize) diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c index e61f90b2cef9..592c09b49d4b 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c @@ -43,8 +43,8 @@ extern __llvm_profile_data PROF_DATA_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; extern __llvm_profile_data PROF_DATA_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; -extern uint64_t PROF_CNTS_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; -extern uint64_t PROF_CNTS_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; +extern char PROF_CNTS_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; +extern char PROF_CNTS_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; extern uint32_t PROF_ORDERFILE_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; extern char PROF_NAME_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; extern char PROF_NAME_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; @@ -65,10 +65,10 @@ COMPILER_RT_VISIBILITY const char *__llvm_profile_begin_names(void) { COMPILER_RT_VISIBILITY const char *__llvm_profile_end_names(void) { return &PROF_NAME_STOP; } -COMPILER_RT_VISIBILITY uint64_t *__llvm_profile_begin_counters(void) { +COMPILER_RT_VISIBILITY char *__llvm_profile_begin_counters(void) { return &PROF_CNTS_START; } -COMPILER_RT_VISIBILITY uint64_t *__llvm_profile_end_counters(void) { +COMPILER_RT_VISIBILITY char *__llvm_profile_end_counters(void) { return &PROF_CNTS_STOP; } COMPILER_RT_VISIBILITY uint32_t *__llvm_profile_begin_orderfile(void) { @@ -125,11 +125,9 @@ static int WriteOneBinaryId(ProfDataWriter *Writer, uint64_t BinaryIdLen, static int WriteBinaryIdForNote(ProfDataWriter *Writer, const ElfW(Nhdr) * Note) { int BinaryIdSize = 0; - const char *NoteName = (const char *)Note + sizeof(ElfW(Nhdr)); if (Note->n_type == NT_GNU_BUILD_ID && Note->n_namesz == 4 && memcmp(NoteName, "GNU\0", 4) == 0) { - uint64_t BinaryIdLen = Note->n_descsz; const uint8_t *BinaryIdData = (const uint8_t *)(NoteName + RoundUp(Note->n_namesz, 4)); @@ -151,12 +149,12 @@ static int WriteBinaryIdForNote(ProfDataWriter *Writer, */ static int WriteBinaryIds(ProfDataWriter *Writer, const ElfW(Nhdr) * Note, const ElfW(Nhdr) * NotesEnd) { - int TotalBinaryIdsSize = 0; + int BinaryIdsSize = 0; while (Note < NotesEnd) { - int Result = WriteBinaryIdForNote(Writer, Note); - if (Result == -1) + int OneBinaryIdSize = WriteBinaryIdForNote(Writer, Note); + if (OneBinaryIdSize == -1) return -1; - TotalBinaryIdsSize += Result; + BinaryIdsSize += OneBinaryIdSize; /* Calculate the offset of the next note in notes section. */ size_t NoteOffset = sizeof(ElfW(Nhdr)) + RoundUp(Note->n_namesz, 4) + @@ -164,7 +162,7 @@ static int WriteBinaryIds(ProfDataWriter *Writer, const ElfW(Nhdr) * Note, Note = (const ElfW(Nhdr) *)((const char *)(Note) + NoteOffset); } - return TotalBinaryIdsSize; + return BinaryIdsSize; } /* @@ -178,21 +176,46 @@ COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) { const ElfW(Phdr) *ProgramHeader = (const ElfW(Phdr) *)((uintptr_t)ElfHeader + ElfHeader->e_phoff); + int TotalBinaryIdsSize = 0; uint32_t I; /* Iterate through entries in the program header. */ for (I = 0; I < ElfHeader->e_phnum; I++) { - /* Look for the notes section in program header entries. */ + /* Look for the notes segment in program header entries. */ if (ProgramHeader[I].p_type != PT_NOTE) continue; - const ElfW(Nhdr) *Note = - (const ElfW(Nhdr) *)((uintptr_t)ElfHeader + ProgramHeader[I].p_offset); - const ElfW(Nhdr) *NotesEnd = - (const ElfW(Nhdr) *)((const char *)(Note) + ProgramHeader[I].p_filesz); - return WriteBinaryIds(Writer, Note, NotesEnd); + /* There can be multiple notes segment, and examine each of them. */ + const ElfW(Nhdr) * Note; + const ElfW(Nhdr) * NotesEnd; + /* + * When examining notes in file, use p_offset, which is the offset within + * the elf file, to find the start of notes. + */ + if (ProgramHeader[I].p_memsz == 0 || + ProgramHeader[I].p_memsz == ProgramHeader[I].p_filesz) { + Note = (const ElfW(Nhdr) *)((uintptr_t)ElfHeader + + ProgramHeader[I].p_offset); + NotesEnd = (const ElfW(Nhdr) *)((const char *)(Note) + + ProgramHeader[I].p_filesz); + } else { + /* + * When examining notes in memory, use p_vaddr, which is the address of + * section after loaded to memory, to find the start of notes. + */ + Note = + (const ElfW(Nhdr) *)((uintptr_t)ElfHeader + ProgramHeader[I].p_vaddr); + NotesEnd = + (const ElfW(Nhdr) *)((const char *)(Note) + ProgramHeader[I].p_memsz); + } + + int BinaryIdsSize = WriteBinaryIds(Writer, Note, NotesEnd); + if (TotalBinaryIdsSize == -1) + return -1; + + TotalBinaryIdsSize += BinaryIdsSize; } - return 0; + return TotalBinaryIdsSize; } #else /* !NT_GNU_BUILD_ID */ /* diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformOther.c contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformOther.c index 48946ce94253..3e9b3ca0a045 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformOther.c +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformOther.c @@ -20,8 +20,8 @@ static const __llvm_profile_data *DataFirst = NULL; static const __llvm_profile_data *DataLast = NULL; static const char *NamesFirst = NULL; static const char *NamesLast = NULL; -static uint64_t *CountersFirst = NULL; -static uint64_t *CountersLast = NULL; +static char *CountersFirst = NULL; +static char *CountersLast = NULL; static uint32_t *OrderFileFirst = NULL; static const void *getMinAddr(const void *A1, const void *A2) { @@ -46,19 +46,21 @@ void __llvm_profile_register_function(void *Data_) { if (!DataFirst) { DataFirst = Data; DataLast = Data + 1; - CountersFirst = (uint64_t *)((uintptr_t)Data_ + Data->CounterPtr); - CountersLast = CountersFirst + Data->NumCounters; + CountersFirst = (char *)((uintptr_t)Data_ + Data->CounterPtr); + CountersLast = + CountersFirst + Data->NumCounters * __llvm_profile_counter_entry_size(); return; } DataFirst = (const __llvm_profile_data *)getMinAddr(DataFirst, Data); - CountersFirst = (uint64_t *)getMinAddr( - CountersFirst, (uint64_t *)((uintptr_t)Data_ + Data->CounterPtr)); + CountersFirst = (char *)getMinAddr( + CountersFirst, (char *)((uintptr_t)Data_ + Data->CounterPtr)); DataLast = (const __llvm_profile_data *)getMaxAddr(DataLast, Data + 1); - CountersLast = (uint64_t *)getMaxAddr( + CountersLast = (char *)getMaxAddr( CountersLast, - (uint64_t *)((uintptr_t)Data_ + Data->CounterPtr) + Data->NumCounters); + (char *)((uintptr_t)Data_ + Data->CounterPtr) + + Data->NumCounters * __llvm_profile_counter_entry_size()); } COMPILER_RT_VISIBILITY @@ -83,9 +85,9 @@ const char *__llvm_profile_begin_names(void) { return NamesFirst; } COMPILER_RT_VISIBILITY const char *__llvm_profile_end_names(void) { return NamesLast; } COMPILER_RT_VISIBILITY -uint64_t *__llvm_profile_begin_counters(void) { return CountersFirst; } +char *__llvm_profile_begin_counters(void) { return CountersFirst; } COMPILER_RT_VISIBILITY -uint64_t *__llvm_profile_end_counters(void) { return CountersLast; } +char *__llvm_profile_end_counters(void) { return CountersLast; } /* TODO: correctly set up OrderFileFirst. */ COMPILER_RT_VISIBILITY uint32_t *__llvm_profile_begin_orderfile(void) { return OrderFileFirst; } diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c index a0192ced4f26..dd576b2f8357 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c @@ -41,8 +41,8 @@ __llvm_profile_data COMPILER_RT_SECTION(".lprfd$Z") DataEnd = {0}; const char COMPILER_RT_SECTION(".lprfn$A") NamesStart = '\0'; const char COMPILER_RT_SECTION(".lprfn$Z") NamesEnd = '\0'; -uint64_t COMPILER_RT_SECTION(".lprfc$A") CountersStart; -uint64_t COMPILER_RT_SECTION(".lprfc$Z") CountersEnd; +char COMPILER_RT_SECTION(".lprfc$A") CountersStart; +char COMPILER_RT_SECTION(".lprfc$Z") CountersEnd; uint32_t COMPILER_RT_SECTION(".lorderfile$A") OrderFileStart; ValueProfNode COMPILER_RT_SECTION(".lprfnd$A") VNodesStart; @@ -56,8 +56,8 @@ const __llvm_profile_data *__llvm_profile_end_data(void) { return &DataEnd; } const char *__llvm_profile_begin_names(void) { return &NamesStart + 1; } const char *__llvm_profile_end_names(void) { return &NamesEnd; } -uint64_t *__llvm_profile_begin_counters(void) { return &CountersStart + 1; } -uint64_t *__llvm_profile_end_counters(void) { return &CountersEnd; } +char *__llvm_profile_begin_counters(void) { return &CountersStart + 1; } +char *__llvm_profile_end_counters(void) { return &CountersEnd; } uint32_t *__llvm_profile_begin_orderfile(void) { return &OrderFileStart; } ValueProfNode *__llvm_profile_begin_vnodes(void) { return &VNodesStart + 1; } diff --git contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingWriter.c contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingWriter.c index e5c0dc1479d9..800103d199ab 100644 --- contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingWriter.c +++ contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingWriter.c @@ -244,8 +244,8 @@ COMPILER_RT_VISIBILITY int lprofWriteData(ProfDataWriter *Writer, /* Match logic in __llvm_profile_write_buffer(). */ const __llvm_profile_data *DataBegin = __llvm_profile_begin_data(); const __llvm_profile_data *DataEnd = __llvm_profile_end_data(); - const uint64_t *CountersBegin = __llvm_profile_begin_counters(); - const uint64_t *CountersEnd = __llvm_profile_end_counters(); + const char *CountersBegin = __llvm_profile_begin_counters(); + const char *CountersEnd = __llvm_profile_end_counters(); const char *NamesBegin = __llvm_profile_begin_names(); const char *NamesEnd = __llvm_profile_end_names(); return lprofWriteDataImpl(Writer, DataBegin, DataEnd, CountersBegin, @@ -256,7 +256,7 @@ COMPILER_RT_VISIBILITY int lprofWriteData(ProfDataWriter *Writer, COMPILER_RT_VISIBILITY int lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, - const uint64_t *CountersBegin, const uint64_t *CountersEnd, + const char *CountersBegin, const char *CountersEnd, VPDataReaderType *VPDataReader, const char *NamesBegin, const char *NamesEnd, int SkipNameDataWrite) { int DebugInfoCorrelate = @@ -265,13 +265,18 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin, /* Calculate size of sections. */ const uint64_t DataSize = DebugInfoCorrelate ? 0 : __llvm_profile_get_data_size(DataBegin, DataEnd); - const uint64_t CountersSize = CountersEnd - CountersBegin; + const uint64_t NumData = + DebugInfoCorrelate ? 0 : __llvm_profile_get_num_data(DataBegin, DataEnd); + const uint64_t CountersSize = + __llvm_profile_get_counters_size(CountersBegin, CountersEnd); + const uint64_t NumCounters = + __llvm_profile_get_num_counters(CountersBegin, CountersEnd); const uint64_t NamesSize = DebugInfoCorrelate ? 0 : NamesEnd - NamesBegin; /* Create the header. */ __llvm_profile_header Header; - if (!DataSize && (!DebugInfoCorrelate || !CountersSize)) + if (!NumData && (!DebugInfoCorrelate || !NumCounters)) return 0; /* Determine how much padding is needed before/after the counters and after @@ -282,9 +287,16 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin, DataSize, CountersSize, NamesSize, &PaddingBytesBeforeCounters, &PaddingBytesAfterCounters, &PaddingBytesAfterNames); + { + // TODO: Unfortunately the header's fields are named DataSize and + // CountersSize when they should be named NumData and NumCounters, + // respectively. + const uint64_t CountersSize = NumCounters; + const uint64_t DataSize = NumData; /* Initialize header structure. */ #define INSTR_PROF_RAW_HEADER(Type, Name, Init) Header.Name = Init; #include "profile/InstrProfData.inc" + } /* On WIN64, label differences are truncated 32-bit values. Truncate * CountersDelta to match. */ @@ -309,10 +321,9 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin, /* Write the profile data. */ ProfDataIOVec IOVecData[] = { - {DebugInfoCorrelate ? NULL : DataBegin, sizeof(__llvm_profile_data), - DataSize, 0}, + {DebugInfoCorrelate ? NULL : DataBegin, sizeof(uint8_t), DataSize, 0}, {NULL, sizeof(uint8_t), PaddingBytesBeforeCounters, 1}, - {CountersBegin, sizeof(uint64_t), CountersSize, 0}, + {CountersBegin, sizeof(uint8_t), CountersSize, 0}, {NULL, sizeof(uint8_t), PaddingBytesAfterCounters, 1}, {(SkipNameDataWrite || DebugInfoCorrelate) ? NULL : NamesBegin, sizeof(uint8_t), NamesSize, 0}, diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_addrhashmap.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_addrhashmap.h index 7e2fa91089f1..fe48b9caf067 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_addrhashmap.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_addrhashmap.h @@ -201,7 +201,8 @@ AddrHashMap<T, kSize>::AddrHashMap() { } template <typename T, uptr kSize> -void AddrHashMap<T, kSize>::acquire(Handle *h) NO_THREAD_SAFETY_ANALYSIS { +void AddrHashMap<T, kSize>::acquire(Handle *h) + SANITIZER_NO_THREAD_SAFETY_ANALYSIS { uptr addr = h->addr_; uptr hash = calcHash(addr); Bucket *b = &table_[hash]; @@ -330,7 +331,8 @@ void AddrHashMap<T, kSize>::acquire(Handle *h) NO_THREAD_SAFETY_ANALYSIS { } template <typename T, uptr kSize> - void AddrHashMap<T, kSize>::release(Handle *h) NO_THREAD_SAFETY_ANALYSIS { + void AddrHashMap<T, kSize>::release(Handle *h) + SANITIZER_NO_THREAD_SAFETY_ANALYSIS { if (!h->cell_) return; Bucket *b = h->bucket_; diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp index c5a5fb7371dd..25a43a59f047 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp @@ -126,12 +126,12 @@ void InternalFree(void *addr, InternalAllocatorCache *cache) { RawInternalFree(addr, cache); } -void InternalAllocatorLock() NO_THREAD_SAFETY_ANALYSIS { +void InternalAllocatorLock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { internal_allocator_cache_mu.Lock(); internal_allocator()->ForceLock(); } -void InternalAllocatorUnlock() NO_THREAD_SAFETY_ANALYSIS { +void InternalAllocatorUnlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { internal_allocator()->ForceUnlock(); internal_allocator_cache_mu.Unlock(); } diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h index 9a3602f730b3..b92cfa5bf4c4 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h @@ -175,12 +175,12 @@ class CombinedAllocator { // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone // introspection API. - void ForceLock() NO_THREAD_SAFETY_ANALYSIS { + void ForceLock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { primary_.ForceLock(); secondary_.ForceLock(); } - void ForceUnlock() NO_THREAD_SAFETY_ANALYSIS { + void ForceUnlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { secondary_.ForceUnlock(); primary_.ForceUnlock(); } diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h index ae1b7e0d5f1c..f2471efced61 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h @@ -238,13 +238,13 @@ class SizeClassAllocator32 { // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone // introspection API. - void ForceLock() NO_THREAD_SAFETY_ANALYSIS { + void ForceLock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { for (uptr i = 0; i < kNumClasses; i++) { GetSizeClassInfo(i)->mutex.Lock(); } } - void ForceUnlock() NO_THREAD_SAFETY_ANALYSIS { + void ForceUnlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { for (int i = kNumClasses - 1; i >= 0; i--) { GetSizeClassInfo(i)->mutex.Unlock(); } diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h index f917310cfebb..66ba71d325da 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h @@ -354,13 +354,13 @@ class SizeClassAllocator64 { // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone // introspection API. - void ForceLock() NO_THREAD_SAFETY_ANALYSIS { + void ForceLock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { for (uptr i = 0; i < kNumClasses; i++) { GetRegionInfo(i)->mutex.Lock(); } } - void ForceUnlock() NO_THREAD_SAFETY_ANALYSIS { + void ForceUnlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { for (int i = (int)kNumClasses - 1; i >= 0; i--) { GetRegionInfo(i)->mutex.Unlock(); } diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h index c24354cb5b2a..48afb2a29834 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h @@ -267,9 +267,9 @@ class LargeMmapAllocator { // ForceLock() and ForceUnlock() are needed to implement Darwin malloc zone // introspection API. - void ForceLock() ACQUIRE(mutex_) { mutex_.Lock(); } + void ForceLock() SANITIZER_ACQUIRE(mutex_) { mutex_.Lock(); } - void ForceUnlock() RELEASE(mutex_) { mutex_.Unlock(); } + void ForceUnlock() SANITIZER_RELEASE(mutex_) { mutex_.Unlock(); } // Iterate over all existing chunks. // The allocator must be locked when calling this function. diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 9ddb099a8dbc..139d5a066664 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -238,12 +238,12 @@ void SetPrintfAndReportCallback(void (*callback)(const char *)); // Lock sanitizer error reporting and protects against nested errors. class ScopedErrorReportLock { public: - ScopedErrorReportLock() ACQUIRE(mutex_) { Lock(); } - ~ScopedErrorReportLock() RELEASE(mutex_) { Unlock(); } + ScopedErrorReportLock() SANITIZER_ACQUIRE(mutex_) { Lock(); } + ~ScopedErrorReportLock() SANITIZER_RELEASE(mutex_) { Unlock(); } - static void Lock() ACQUIRE(mutex_); - static void Unlock() RELEASE(mutex_); - static void CheckLocked() CHECK_LOCKED(mutex_); + static void Lock() SANITIZER_ACQUIRE(mutex_); + static void Unlock() SANITIZER_RELEASE(mutex_); + static void CheckLocked() SANITIZER_CHECK_LOCKED(mutex_); private: static atomic_uintptr_t reporting_thread_; diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index 52fd4f3e6d41..54a7ad3b8b3f 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -606,8 +606,9 @@ static int AddModuleSegments(const char *module_name, dl_phdr_info *info, cur_module.addAddressRange(cur_beg, cur_end, executable, writable); } else if (phdr->p_type == PT_NOTE) { +# ifdef NT_GNU_BUILD_ID uptr off = 0; - while (off < phdr->p_memsz - sizeof(ElfW(Nhdr))) { + while (off + sizeof(ElfW(Nhdr)) < phdr->p_memsz) { auto *nhdr = reinterpret_cast<const ElfW(Nhdr) *>(info->dlpi_addr + phdr->p_vaddr + off); constexpr auto kGnuNamesz = 4; // "GNU" with NUL-byte. @@ -631,6 +632,7 @@ static int AddModuleSegments(const char *module_name, dl_phdr_info *info, off += sizeof(*nhdr) + RoundUpTo(nhdr->n_namesz, 4) + RoundUpTo(nhdr->n_descsz, 4); } +# endif } } modules->push_back(cur_module); diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h index 5ec6efaa6490..c16f5cdc1d71 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h @@ -20,25 +20,27 @@ namespace __sanitizer { -class MUTEX StaticSpinMutex { +class SANITIZER_MUTEX StaticSpinMutex { public: void Init() { atomic_store(&state_, 0, memory_order_relaxed); } - void Lock() ACQUIRE() { + void Lock() SANITIZER_ACQUIRE() { if (LIKELY(TryLock())) return; LockSlow(); } - bool TryLock() TRY_ACQUIRE(true) { + bool TryLock() SANITIZER_TRY_ACQUIRE(true) { return atomic_exchange(&state_, 1, memory_order_acquire) == 0; } - void Unlock() RELEASE() { atomic_store(&state_, 0, memory_order_release); } + void Unlock() SANITIZER_RELEASE() { + atomic_store(&state_, 0, memory_order_release); + } - void CheckLocked() const CHECK_LOCKED() { + void CheckLocked() const SANITIZER_CHECK_LOCKED() { CHECK_EQ(atomic_load(&state_, memory_order_relaxed), 1); } @@ -48,7 +50,7 @@ class MUTEX StaticSpinMutex { void LockSlow(); }; -class MUTEX SpinMutex : public StaticSpinMutex { +class SANITIZER_MUTEX SpinMutex : public StaticSpinMutex { public: SpinMutex() { Init(); @@ -156,12 +158,12 @@ class CheckedMutex { // Derive from CheckedMutex for the purposes of EBO. // We could make it a field marked with [[no_unique_address]], // but this attribute is not supported by some older compilers. -class MUTEX Mutex : CheckedMutex { +class SANITIZER_MUTEX Mutex : CheckedMutex { public: explicit constexpr Mutex(MutexType type = MutexUnchecked) : CheckedMutex(type) {} - void Lock() ACQUIRE() { + void Lock() SANITIZER_ACQUIRE() { CheckedMutex::Lock(); u64 reset_mask = ~0ull; u64 state = atomic_load_relaxed(&state_); @@ -206,7 +208,7 @@ class MUTEX Mutex : CheckedMutex { } } - void Unlock() RELEASE() { + void Unlock() SANITIZER_RELEASE() { CheckedMutex::Unlock(); bool wake_writer; u64 wake_readers; @@ -234,7 +236,7 @@ class MUTEX Mutex : CheckedMutex { readers_.Post(wake_readers); } - void ReadLock() ACQUIRE_SHARED() { + void ReadLock() SANITIZER_ACQUIRE_SHARED() { CheckedMutex::Lock(); u64 reset_mask = ~0ull; u64 state = atomic_load_relaxed(&state_); @@ -271,7 +273,7 @@ class MUTEX Mutex : CheckedMutex { } } - void ReadUnlock() RELEASE_SHARED() { + void ReadUnlock() SANITIZER_RELEASE_SHARED() { CheckedMutex::Unlock(); bool wake; u64 new_state; @@ -297,13 +299,13 @@ class MUTEX Mutex : CheckedMutex { // owns the mutex but a child checks that it is locked. Rather than // maintaining complex state to work around those situations, the check only // checks that the mutex is owned. - void CheckWriteLocked() const CHECK_LOCKED() { + void CheckWriteLocked() const SANITIZER_CHECK_LOCKED() { CHECK(atomic_load(&state_, memory_order_relaxed) & kWriterLock); } - void CheckLocked() const CHECK_LOCKED() { CheckWriteLocked(); } + void CheckLocked() const SANITIZER_CHECK_LOCKED() { CheckWriteLocked(); } - void CheckReadLocked() const CHECK_LOCKED() { + void CheckReadLocked() const SANITIZER_CHECK_LOCKED() { CHECK(atomic_load(&state_, memory_order_relaxed) & kReaderLockMask); } @@ -361,13 +363,13 @@ void FutexWait(atomic_uint32_t *p, u32 cmp); void FutexWake(atomic_uint32_t *p, u32 count); template <typename MutexType> -class SCOPED_LOCK GenericScopedLock { +class SANITIZER_SCOPED_LOCK GenericScopedLock { public: - explicit GenericScopedLock(MutexType *mu) ACQUIRE(mu) : mu_(mu) { + explicit GenericScopedLock(MutexType *mu) SANITIZER_ACQUIRE(mu) : mu_(mu) { mu_->Lock(); } - ~GenericScopedLock() RELEASE() { mu_->Unlock(); } + ~GenericScopedLock() SANITIZER_RELEASE() { mu_->Unlock(); } private: MutexType *mu_; @@ -377,13 +379,14 @@ class SCOPED_LOCK GenericScopedLock { }; template <typename MutexType> -class SCOPED_LOCK GenericScopedReadLock { +class SANITIZER_SCOPED_LOCK GenericScopedReadLock { public: - explicit GenericScopedReadLock(MutexType *mu) ACQUIRE(mu) : mu_(mu) { + explicit GenericScopedReadLock(MutexType *mu) SANITIZER_ACQUIRE(mu) + : mu_(mu) { mu_->ReadLock(); } - ~GenericScopedReadLock() RELEASE() { mu_->ReadUnlock(); } + ~GenericScopedReadLock() SANITIZER_RELEASE() { mu_->ReadUnlock(); } private: MutexType *mu_; @@ -393,10 +396,10 @@ class SCOPED_LOCK GenericScopedReadLock { }; template <typename MutexType> -class SCOPED_LOCK GenericScopedRWLock { +class SANITIZER_SCOPED_LOCK GenericScopedRWLock { public: ALWAYS_INLINE explicit GenericScopedRWLock(MutexType *mu, bool write) - ACQUIRE(mu) + SANITIZER_ACQUIRE(mu) : mu_(mu), write_(write) { if (write_) mu_->Lock(); @@ -404,7 +407,7 @@ class SCOPED_LOCK GenericScopedRWLock { mu_->ReadLock(); } - ALWAYS_INLINE ~GenericScopedRWLock() RELEASE() { + ALWAYS_INLINE ~GenericScopedRWLock() SANITIZER_RELEASE() { if (write_) mu_->Unlock(); else diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp index 64535805e40d..0d25fa80e2ed 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp @@ -130,7 +130,7 @@ unsigned struct_sigevent_sz = sizeof(struct sigevent); unsigned struct_sched_param_sz = sizeof(struct sched_param); unsigned struct_statfs_sz = sizeof(struct statfs); unsigned struct_sockaddr_sz = sizeof(struct sockaddr); -unsigned ucontext_t_sz = sizeof(ucontext_t); +unsigned ucontext_t_sz(void *ctx) { return sizeof(ucontext_t); } unsigned struct_rlimit_sz = sizeof(struct rlimit); unsigned struct_timespec_sz = sizeof(struct timespec); unsigned struct_utimbuf_sz = sizeof(struct utimbuf); diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h index 649e64fd1a32..9859c52ec69f 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h @@ -57,7 +57,7 @@ extern unsigned struct_sched_param_sz; extern unsigned struct_statfs64_sz; extern unsigned struct_statfs_sz; extern unsigned struct_sockaddr_sz; -extern unsigned ucontext_t_sz; +unsigned ucontext_t_sz(void *ctx); extern unsigned struct_rlimit_sz; extern unsigned struct_utimbuf_sz; extern unsigned struct_timespec_sz; diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp index 531e07f2d4c5..648e502b904a 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp @@ -554,7 +554,7 @@ unsigned struct_tms_sz = sizeof(struct tms); unsigned struct_sigevent_sz = sizeof(struct sigevent); unsigned struct_sched_param_sz = sizeof(struct sched_param); unsigned struct_sockaddr_sz = sizeof(struct sockaddr); -unsigned ucontext_t_sz = sizeof(ucontext_t); +unsigned ucontext_t_sz(void *ctx) { return sizeof(ucontext_t); } unsigned struct_rlimit_sz = sizeof(struct rlimit); unsigned struct_timespec_sz = sizeof(struct timespec); unsigned struct_sembuf_sz = sizeof(struct sembuf); diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h index 9407803fc9c3..dc6eb59b2800 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -45,7 +45,7 @@ extern unsigned struct_stack_t_sz; extern unsigned struct_sched_param_sz; extern unsigned struct_statfs_sz; extern unsigned struct_sockaddr_sz; -extern unsigned ucontext_t_sz; +unsigned ucontext_t_sz(void *ctx); extern unsigned struct_rlimit_sz; extern unsigned struct_utimbuf_sz; diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index a1c452855ae7..82048f0eae2e 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -170,8 +170,9 @@ typedef struct user_fpregs elf_fpregset_t; #endif // Include these after system headers to avoid name clashes and ambiguities. -#include "sanitizer_internal_defs.h" -#include "sanitizer_platform_limits_posix.h" +# include "sanitizer_common.h" +# include "sanitizer_internal_defs.h" +# include "sanitizer_platform_limits_posix.h" namespace __sanitizer { unsigned struct_utsname_sz = sizeof(struct utsname); @@ -214,10 +215,24 @@ namespace __sanitizer { #if !SANITIZER_ANDROID unsigned struct_statfs_sz = sizeof(struct statfs); unsigned struct_sockaddr_sz = sizeof(struct sockaddr); - unsigned ucontext_t_sz = sizeof(ucontext_t); -#endif // !SANITIZER_ANDROID -#if SANITIZER_LINUX + unsigned ucontext_t_sz(void *ctx) { +# if SANITIZER_LINUX && SANITIZER_X64 + // See kernel arch/x86/kernel/fpu/signal.c for details. + const auto *fpregs = static_cast<ucontext_t *>(ctx)->uc_mcontext.fpregs; + // The member names differ across header versions, but the actual layout + // is always the same. So avoid using members, just use arithmetic. + const uint32_t *after_xmm = + reinterpret_cast<const uint32_t *>(fpregs + 1) - 24; + if (after_xmm[12] == FP_XSTATE_MAGIC1) + return reinterpret_cast<const char *>(fpregs) + after_xmm[13] - + static_cast<const char *>(ctx); +# endif + return sizeof(ucontext_t); + } +# endif // !SANITIZER_ANDROID + +# if SANITIZER_LINUX unsigned struct_epoll_event_sz = sizeof(struct epoll_event); unsigned struct_sysinfo_sz = sizeof(struct sysinfo); unsigned __user_cap_header_struct_sz = diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 6de1e8e14a4f..89f323dd2c72 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -57,12 +57,12 @@ extern unsigned struct_regmatch_sz; extern unsigned struct_fstab_sz; extern unsigned struct_statfs_sz; extern unsigned struct_sockaddr_sz; -extern unsigned ucontext_t_sz; -#endif // !SANITIZER_ANDROID +unsigned ucontext_t_sz(void *uctx); +# endif // !SANITIZER_ANDROID -#if SANITIZER_LINUX +# if SANITIZER_LINUX -#if defined(__x86_64__) +# if defined(__x86_64__) const unsigned struct_kernel_stat_sz = 144; const unsigned struct_kernel_stat64_sz = 0; #elif defined(__i386__) diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_solaris.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_solaris.cpp index a113cb0d3490..dad7bde1498a 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_solaris.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_solaris.cpp @@ -89,7 +89,7 @@ namespace __sanitizer { unsigned struct_sched_param_sz = sizeof(struct sched_param); unsigned struct_statfs_sz = sizeof(struct statfs); unsigned struct_sockaddr_sz = sizeof(struct sockaddr); - unsigned ucontext_t_sz = sizeof(ucontext_t); + unsigned ucontext_t_sz(void *ctx) { return sizeof(ucontext_t); } unsigned struct_timespec_sz = sizeof(struct timespec); #if SANITIZER_SOLARIS32 unsigned struct_statvfs64_sz = sizeof(struct statvfs64); diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_solaris.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_solaris.h index cbab577bcf26..84a81265162c 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_solaris.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_solaris.h @@ -43,7 +43,7 @@ extern unsigned struct_sched_param_sz; extern unsigned struct_statfs64_sz; extern unsigned struct_statfs_sz; extern unsigned struct_sockaddr_sz; -extern unsigned ucontext_t_sz; +unsigned ucontext_t_sz(void *ctx); extern unsigned struct_timespec_sz; extern unsigned struct_rlimit_sz; diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp index 1f53e3e46d8f..62b2e5e03216 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp @@ -143,16 +143,16 @@ void MemoryMappingLayout::LoadFromCache() { // early in the process, when dyld is one of the only images loaded, // so it will be hit after only a few iterations. static mach_header *get_dyld_image_header() { - unsigned depth = 1; - vm_size_t size = 0; vm_address_t address = 0; - kern_return_t err = KERN_SUCCESS; - mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; while (true) { + vm_size_t size = 0; + unsigned depth = 1; struct vm_region_submap_info_64 info; - err = vm_region_recurse_64(mach_task_self(), &address, &size, &depth, - (vm_region_info_t)&info, &count); + mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; + kern_return_t err = + vm_region_recurse_64(mach_task_self(), &address, &size, &depth, + (vm_region_info_t)&info, &count); if (err != KERN_SUCCESS) return nullptr; if (size >= sizeof(mach_header) && info.protection & kProtectionRead) { diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_quarantine.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_quarantine.h index 1a074d2bb700..4aa605485166 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_quarantine.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_quarantine.h @@ -149,8 +149,8 @@ class Quarantine { Cache cache_; char pad2_[kCacheLineSize]; - void NOINLINE Recycle(uptr min_size, Callback cb) REQUIRES(recycle_mutex_) - RELEASE(recycle_mutex_) { + void NOINLINE Recycle(uptr min_size, Callback cb) + SANITIZER_REQUIRES(recycle_mutex_) SANITIZER_RELEASE(recycle_mutex_) { Cache tmp; { SpinMutexLock l(&cache_mutex_); diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp index 4791a3a35bdb..148470943b47 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp @@ -234,6 +234,11 @@ static uptr *UncompressLzw(const u8 *from, const u8 *from_end, uptr *to, return to; } +#if defined(_MSC_VER) && !defined(__clang__) +# pragma warning(push) +// Disable 'nonstandard extension used: zero-sized array in struct/union'. +# pragma warning(disable : 4200) +#endif namespace { struct PackedHeader { uptr size; @@ -241,6 +246,9 @@ struct PackedHeader { u8 data[]; }; } // namespace +#if defined(_MSC_VER) && !defined(__clang__) +# pragma warning(pop) +#endif uptr *StackStore::BlockInfo::GetOrUnpack(StackStore *store) { SpinMutexLock l(&mtx_); diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h index 1bfad811f712..4f1a8caac6ed 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h @@ -97,7 +97,7 @@ class StackStore { Packed, Unpacked, }; - State state GUARDED_BY(mtx_); + State state SANITIZER_GUARDED_BY(mtx_); uptr *Create(StackStore *store); @@ -109,8 +109,8 @@ class StackStore { void TestOnlyUnmap(StackStore *store); bool Stored(uptr n); bool IsPacked() const; - void Lock() NO_THREAD_SAFETY_ANALYSIS { mtx_.Lock(); } - void Unlock() NO_THREAD_SAFETY_ANALYSIS { mtx_.Unlock(); } + void Lock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { mtx_.Lock(); } + void Unlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { mtx_.Unlock(); } }; BlockInfo blocks_[kBlockCount] = {}; diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp index c755b1829d2a..ac87fab3eaf1 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp @@ -94,8 +94,8 @@ class CompressThread { constexpr CompressThread() = default; void NewWorkNotify(); void Stop(); - void LockAndStop() NO_THREAD_SAFETY_ANALYSIS; - void Unlock() NO_THREAD_SAFETY_ANALYSIS; + void LockAndStop() SANITIZER_NO_THREAD_SAFETY_ANALYSIS; + void Unlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS; private: enum class State { @@ -114,8 +114,8 @@ class CompressThread { Semaphore semaphore_ = {}; StaticSpinMutex mutex_ = {}; - State state_ GUARDED_BY(mutex_) = State::NotStarted; - void *thread_ GUARDED_BY(mutex_) = nullptr; + State state_ SANITIZER_GUARDED_BY(mutex_) = State::NotStarted; + void *thread_ SANITIZER_GUARDED_BY(mutex_) = nullptr; atomic_uint8_t run_ = {}; }; diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_win.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_win.cpp index e12b9e5bee06..f114acea79c9 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_win.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_win.cpp @@ -122,7 +122,7 @@ DWORD WINAPI RunThread(void *argument) { OpenThread(THREAD_ALL_ACCESS, FALSE, thread_entry.th32ThreadID); CHECK(thread); - if (SuspendThread(thread) == -1) { + if (SuspendThread(thread) == (DWORD)-1) { DWORD last_error = GetLastError(); VPrintf(1, "Could not suspend thread %lu (error %lu)", diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_syscalls_netbsd.inc contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_syscalls_netbsd.inc index c4a9d99fe2f0..4ce5de062756 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_syscalls_netbsd.inc +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_syscalls_netbsd.inc @@ -2255,13 +2255,13 @@ PRE_SYSCALL(getcontext)(void *ucp_) { /* Nothing to do */ } POST_SYSCALL(getcontext)(long long res, void *ucp_) { /* Nothing to do */ } PRE_SYSCALL(setcontext)(void *ucp_) { if (ucp_) { - PRE_READ(ucp_, ucontext_t_sz); + PRE_READ(ucp_, ucontext_t_sz(ucp_)); } } POST_SYSCALL(setcontext)(long long res, void *ucp_) {} PRE_SYSCALL(_lwp_create)(void *ucp_, long long flags_, void *new_lwp_) { if (ucp_) { - PRE_READ(ucp_, ucontext_t_sz); + PRE_READ(ucp_, ucontext_t_sz(ucp_)); } } POST_SYSCALL(_lwp_create) diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h index 9975d78ec0bb..2c7e5c276fa1 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h @@ -86,7 +86,7 @@ class ThreadContextBase { typedef ThreadContextBase* (*ThreadContextFactory)(u32 tid); -class MUTEX ThreadRegistry { +class SANITIZER_MUTEX ThreadRegistry { public: ThreadRegistry(ThreadContextFactory factory); ThreadRegistry(ThreadContextFactory factory, u32 max_threads, @@ -95,9 +95,9 @@ class MUTEX ThreadRegistry { uptr *alive = nullptr); uptr GetMaxAliveThreads(); - void Lock() ACQUIRE() { mtx_.Lock(); } - void CheckLocked() const CHECK_LOCKED() { mtx_.CheckLocked(); } - void Unlock() RELEASE() { mtx_.Unlock(); } + void Lock() SANITIZER_ACQUIRE() { mtx_.Lock(); } + void CheckLocked() const SANITIZER_CHECK_LOCKED() { mtx_.CheckLocked(); } + void Unlock() SANITIZER_RELEASE() { mtx_.Unlock(); } // Should be guarded by ThreadRegistryLock. ThreadContextBase *GetThreadLocked(u32 tid) { diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_thread_safety.h contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_thread_safety.h index 52b25edaa7a3..c34ea804da20 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_thread_safety.h +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_thread_safety.h @@ -16,27 +16,34 @@ #define SANITIZER_THREAD_SAFETY_H #if defined(__clang__) -# define THREAD_ANNOTATION(x) __attribute__((x)) +# define SANITIZER_THREAD_ANNOTATION(x) __attribute__((x)) #else -# define THREAD_ANNOTATION(x) +# define SANITIZER_THREAD_ANNOTATION(x) #endif -#define MUTEX THREAD_ANNOTATION(capability("mutex")) -#define SCOPED_LOCK THREAD_ANNOTATION(scoped_lockable) -#define GUARDED_BY(x) THREAD_ANNOTATION(guarded_by(x)) -#define PT_GUARDED_BY(x) THREAD_ANNOTATION(pt_guarded_by(x)) -#define REQUIRES(...) THREAD_ANNOTATION(requires_capability(__VA_ARGS__)) -#define REQUIRES_SHARED(...) \ - THREAD_ANNOTATION(requires_shared_capability(__VA_ARGS__)) -#define ACQUIRE(...) THREAD_ANNOTATION(acquire_capability(__VA_ARGS__)) -#define ACQUIRE_SHARED(...) \ - THREAD_ANNOTATION(acquire_shared_capability(__VA_ARGS__)) -#define TRY_ACQUIRE(...) THREAD_ANNOTATION(try_acquire_capability(__VA_ARGS__)) -#define RELEASE(...) THREAD_ANNOTATION(release_capability(__VA_ARGS__)) -#define RELEASE_SHARED(...) \ - THREAD_ANNOTATION(release_shared_capability(__VA_ARGS__)) -#define EXCLUDES(...) THREAD_ANNOTATION(locks_excluded(__VA_ARGS__)) -#define CHECK_LOCKED(...) THREAD_ANNOTATION(assert_capability(__VA_ARGS__)) -#define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION(no_thread_safety_analysis) +#define SANITIZER_MUTEX SANITIZER_THREAD_ANNOTATION(capability("mutex")) +#define SANITIZER_SCOPED_LOCK SANITIZER_THREAD_ANNOTATION(scoped_lockable) +#define SANITIZER_GUARDED_BY(x) SANITIZER_THREAD_ANNOTATION(guarded_by(x)) +#define SANITIZER_PT_GUARDED_BY(x) SANITIZER_THREAD_ANNOTATION(pt_guarded_by(x)) +#define SANITIZER_REQUIRES(...) \ + SANITIZER_THREAD_ANNOTATION(requires_capability(__VA_ARGS__)) +#define SANITIZER_REQUIRES_SHARED(...) \ + SANITIZER_THREAD_ANNOTATION(requires_shared_capability(__VA_ARGS__)) +#define SANITIZER_ACQUIRE(...) \ + SANITIZER_THREAD_ANNOTATION(acquire_capability(__VA_ARGS__)) +#define SANITIZER_ACQUIRE_SHARED(...) \ + SANITIZER_THREAD_ANNOTATION(acquire_shared_capability(__VA_ARGS__)) +#define SANITIZER_TRY_ACQUIRE(...) \ + SANITIZER_THREAD_ANNOTATION(try_acquire_capability(__VA_ARGS__)) +#define SANITIZER_RELEASE(...) \ + SANITIZER_THREAD_ANNOTATION(release_capability(__VA_ARGS__)) +#define SANITIZER_RELEASE_SHARED(...) \ + SANITIZER_THREAD_ANNOTATION(release_shared_capability(__VA_ARGS__)) +#define SANITIZER_EXCLUDES(...) \ + SANITIZER_THREAD_ANNOTATION(locks_excluded(__VA_ARGS__)) +#define SANITIZER_CHECK_LOCKED(...) \ + SANITIZER_THREAD_ANNOTATION(assert_capability(__VA_ARGS__)) +#define SANITIZER_NO_THREAD_SAFETY_ANALYSIS \ + SANITIZER_THREAD_ANNOTATION(no_thread_safety_analysis) #endif diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_win.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_win.cpp index 7e01c81d0422..afcd01dae0b7 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_win.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_win.cpp @@ -57,30 +57,37 @@ void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) { InitializeDbgHelpIfNeeded(); size = 0; -#if defined(_WIN64) +# if SANITIZER_WINDOWS64 +# if SANITIZER_ARM64 + int machine_type = IMAGE_FILE_MACHINE_ARM64; + stack_frame.AddrPC.Offset = ctx.Pc; + stack_frame.AddrFrame.Offset = ctx.Fp; + stack_frame.AddrStack.Offset = ctx.Sp; +# else int machine_type = IMAGE_FILE_MACHINE_AMD64; stack_frame.AddrPC.Offset = ctx.Rip; stack_frame.AddrFrame.Offset = ctx.Rbp; stack_frame.AddrStack.Offset = ctx.Rsp; -#else +# endif +# else int machine_type = IMAGE_FILE_MACHINE_I386; stack_frame.AddrPC.Offset = ctx.Eip; stack_frame.AddrFrame.Offset = ctx.Ebp; stack_frame.AddrStack.Offset = ctx.Esp; -#endif +# endif stack_frame.AddrPC.Mode = AddrModeFlat; stack_frame.AddrFrame.Mode = AddrModeFlat; stack_frame.AddrStack.Mode = AddrModeFlat; while (StackWalk64(machine_type, GetCurrentProcess(), GetCurrentThread(), - &stack_frame, &ctx, NULL, SymFunctionTableAccess64, - SymGetModuleBase64, NULL) && - size < Min(max_depth, kStackTraceMax)) { + &stack_frame, &ctx, NULL, SymFunctionTableAccess64, + SymGetModuleBase64, NULL) && + size < Min(max_depth, kStackTraceMax)) { trace_buffer[size++] = (uptr)stack_frame.AddrPC.Offset; } } -#ifdef __clang__ -#pragma clang diagnostic pop -#endif -#endif // #if !SANITIZER_GO +# ifdef __clang__ +# pragma clang diagnostic pop +# endif +# endif // #if !SANITIZER_GO #endif // SANITIZER_WINDOWS diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp index cfe6cc2b394b..87758a4904ab 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -950,13 +950,18 @@ void SignalContext::InitPcSpBp() { CONTEXT *context_record = (CONTEXT *)context; pc = (uptr)exception_record->ExceptionAddress; -#ifdef _WIN64 +# if SANITIZER_WINDOWS64 +# if SANITIZER_ARM64 + bp = (uptr)context_record->Fp; + sp = (uptr)context_record->Sp; +# else bp = (uptr)context_record->Rbp; sp = (uptr)context_record->Rsp; -#else +# endif +# else bp = (uptr)context_record->Ebp; sp = (uptr)context_record->Esp; -#endif +# endif } uptr SignalContext::GetAddress() const { diff --git contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt index 0bb38ba951a8..071dbbb279c6 100644 --- contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt +++ contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt @@ -94,6 +94,7 @@ isxdigit U log10 U lseek U lseek64 U +madvise U malloc U mbrlen U mbrtowc U diff --git contrib/llvm-project/compiler-rt/lib/scudo/scudo_allocator.cpp contrib/llvm-project/compiler-rt/lib/scudo/scudo_allocator.cpp index 172353fadb1f..5b6ac8b35493 100644 --- contrib/llvm-project/compiler-rt/lib/scudo/scudo_allocator.cpp +++ contrib/llvm-project/compiler-rt/lib/scudo/scudo_allocator.cpp @@ -299,8 +299,9 @@ struct Allocator { NOINLINE bool isRssLimitExceeded(); // Allocates a chunk. - void *allocate(uptr Size, uptr Alignment, AllocType Type, - bool ForceZeroContents = false) NO_THREAD_SAFETY_ANALYSIS { + void * + allocate(uptr Size, uptr Alignment, AllocType Type, + bool ForceZeroContents = false) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { initThreadMaybe(); if (UNLIKELY(Alignment > MaxAlignment)) { @@ -404,8 +405,8 @@ struct Allocator { // Place a chunk in the quarantine or directly deallocate it in the event of // a zero-sized quarantine, or if the size of the chunk is greater than the // quarantine chunk size threshold. - void quarantineOrDeallocateChunk(void *Ptr, UnpackedHeader *Header, - uptr Size) NO_THREAD_SAFETY_ANALYSIS { + void quarantineOrDeallocateChunk(void *Ptr, UnpackedHeader *Header, uptr Size) + SANITIZER_NO_THREAD_SAFETY_ANALYSIS { const bool BypassQuarantine = !Size || (Size > QuarantineChunksUpToSize); if (BypassQuarantine) { UnpackedHeader NewHeader = *Header; diff --git contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd.h contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd.h index e1310974db45..eef4a7ba1e65 100644 --- contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd.h +++ contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd.h @@ -29,7 +29,7 @@ struct ALIGNED(SANITIZER_CACHE_LINE_SIZE) ScudoTSD { void init(); void commitBack(); - inline bool tryLock() TRY_ACQUIRE(true, Mutex) { + inline bool tryLock() SANITIZER_TRY_ACQUIRE(true, Mutex) { if (Mutex.TryLock()) { atomic_store_relaxed(&Precedence, 0); return true; @@ -40,12 +40,12 @@ struct ALIGNED(SANITIZER_CACHE_LINE_SIZE) ScudoTSD { return false; } - inline void lock() ACQUIRE(Mutex) { + inline void lock() SANITIZER_ACQUIRE(Mutex) { atomic_store_relaxed(&Precedence, 0); Mutex.Lock(); } - inline void unlock() RELEASE(Mutex) { Mutex.Unlock(); } + inline void unlock() SANITIZER_RELEASE(Mutex) { Mutex.Unlock(); } inline uptr getPrecedence() { return atomic_load_relaxed(&Precedence); } diff --git contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_exclusive.inc contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_exclusive.inc index 29db8a2eff1a..dc4d982f2fa8 100644 --- contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_exclusive.inc +++ contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_exclusive.inc @@ -34,7 +34,7 @@ ALWAYS_INLINE void initThreadMaybe(bool MinimalInit = false) { } ALWAYS_INLINE ScudoTSD * -getTSDAndLock(bool *UnlockRequired) NO_THREAD_SAFETY_ANALYSIS { +getTSDAndLock(bool *UnlockRequired) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { if (UNLIKELY(ScudoThreadState != ThreadInitialized)) { FallbackTSD.lock(); *UnlockRequired = true; diff --git contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_shared.cpp contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_shared.cpp index fd85a7c4017f..fc691b21a213 100644 --- contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_shared.cpp +++ contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_shared.cpp @@ -64,7 +64,7 @@ void initThread(bool MinimalInit) { setCurrentTSD(&TSDs[Index % NumberOfTSDs]); } -ScudoTSD *getTSDAndLockSlow(ScudoTSD *TSD) NO_THREAD_SAFETY_ANALYSIS { +ScudoTSD *getTSDAndLockSlow(ScudoTSD *TSD) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { if (NumberOfTSDs > 1) { // Use the Precedence of the current TSD as our random seed. Since we are in // the slow path, it means that tryLock failed, and as a result it's very diff --git contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_shared.inc contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_shared.inc index e46b044a81f8..b25392a9630e 100644 --- contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_shared.inc +++ contrib/llvm-project/compiler-rt/lib/scudo/scudo_tsd_shared.inc @@ -42,7 +42,7 @@ ALWAYS_INLINE void initThreadMaybe(bool MinimalInit = false) { ScudoTSD *getTSDAndLockSlow(ScudoTSD *TSD); ALWAYS_INLINE ScudoTSD * -getTSDAndLock(bool *UnlockRequired) NO_THREAD_SAFETY_ANALYSIS { +getTSDAndLock(bool *UnlockRequired) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { ScudoTSD *TSD = getCurrentTSD(); DCHECK(TSD && "No TSD associated with the current thread!"); *UnlockRequired = true; diff --git contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_mman.cpp contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_mman.cpp index 75044c38d5d2..86a3dcd332b2 100644 --- contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_mman.cpp +++ contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_mman.cpp @@ -124,13 +124,13 @@ ScopedGlobalProcessor::~ScopedGlobalProcessor() { gp->mtx.Unlock(); } -void AllocatorLock() NO_THREAD_SAFETY_ANALYSIS { +void AllocatorLock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { global_proc()->mtx.Lock(); global_proc()->internal_alloc_mtx.Lock(); InternalAllocatorLock(); } -void AllocatorUnlock() NO_THREAD_SAFETY_ANALYSIS { +void AllocatorUnlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { InternalAllocatorUnlock(); global_proc()->internal_alloc_mtx.Unlock(); global_proc()->mtx.Unlock(); diff --git contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.cpp contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.cpp index c14af9788e32..5b46d5f5e2bc 100644 --- contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.cpp +++ contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.cpp @@ -521,7 +521,7 @@ int Finalize(ThreadState *thr) { } #if !SANITIZER_GO -void ForkBefore(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { +void ForkBefore(ThreadState *thr, uptr pc) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { ctx->thread_registry.Lock(); ctx->report_mtx.Lock(); ScopedErrorReportLock::Lock(); @@ -543,7 +543,8 @@ void ForkBefore(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { __tsan_test_only_on_fork(); } -void ForkParentAfter(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { +void ForkParentAfter(ThreadState *thr, + uptr pc) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { thr->suppress_reports--; // Enabled in ForkBefore. thr->ignore_interceptors--; thr->ignore_reads_and_writes--; @@ -554,7 +555,7 @@ void ForkParentAfter(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { } void ForkChildAfter(ThreadState *thr, uptr pc, - bool start_thread) NO_THREAD_SAFETY_ANALYSIS { + bool start_thread) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { thr->suppress_reports--; // Enabled in ForkBefore. thr->ignore_interceptors--; thr->ignore_reads_and_writes--; diff --git contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 256e92de99d7..425d605d95a7 100644 --- contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -2209,6 +2209,7 @@ void atfork_child() { FdOnFork(thr, pc); } +#if !SANITIZER_IOS TSAN_INTERCEPTOR(int, vfork, int fake) { // Some programs (e.g. openjdk) call close for all file descriptors // in the child process. Under tsan it leads to false positives, because @@ -2225,6 +2226,7 @@ TSAN_INTERCEPTOR(int, vfork, int fake) { // Instead we simply turn vfork into fork. return WRAP(fork)(fake); } +#endif #if SANITIZER_LINUX TSAN_INTERCEPTOR(int, clone, int (*fn)(void *), void *stack, int flags, diff --git contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp index 7a72efb12263..00cc3a306fd3 100644 --- contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp +++ contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp @@ -124,21 +124,21 @@ ScopedGlobalProcessor::~ScopedGlobalProcessor() { gp->mtx.Unlock(); } -void AllocatorLock() NO_THREAD_SAFETY_ANALYSIS { +void AllocatorLock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { global_proc()->internal_alloc_mtx.Lock(); InternalAllocatorLock(); } -void AllocatorUnlock() NO_THREAD_SAFETY_ANALYSIS { +void AllocatorUnlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { InternalAllocatorUnlock(); global_proc()->internal_alloc_mtx.Unlock(); } -void GlobalProcessorLock() NO_THREAD_SAFETY_ANALYSIS { +void GlobalProcessorLock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { global_proc()->mtx.Lock(); } -void GlobalProcessorUnlock() NO_THREAD_SAFETY_ANALYSIS { +void GlobalProcessorUnlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { global_proc()->mtx.Unlock(); } diff --git contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp index ed60e250cff8..c068d8e486b0 100644 --- contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -113,7 +113,7 @@ static TracePart* TracePartAlloc(ThreadState* thr) { return part; } -static void TracePartFree(TracePart* part) REQUIRES(ctx->slot_mtx) { +static void TracePartFree(TracePart* part) SANITIZER_REQUIRES(ctx->slot_mtx) { DCHECK(part->trace); part->trace = nullptr; ctx->trace_part_recycle.PushFront(part); @@ -208,7 +208,7 @@ static void DoResetImpl(uptr epoch) { // Clang does not understand locking all slots in the loop: // error: expecting mutex 'slot.mtx' to be held at start of each loop -void DoReset(ThreadState* thr, uptr epoch) NO_THREAD_SAFETY_ANALYSIS { +void DoReset(ThreadState* thr, uptr epoch) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { { for (auto& slot : ctx->slots) { slot.mtx.Lock(); @@ -230,7 +230,7 @@ void DoReset(ThreadState* thr, uptr epoch) NO_THREAD_SAFETY_ANALYSIS { void FlushShadowMemory() { DoReset(nullptr, 0); } static TidSlot* FindSlotAndLock(ThreadState* thr) - ACQUIRE(thr->slot->mtx) NO_THREAD_SAFETY_ANALYSIS { + SANITIZER_ACQUIRE(thr->slot->mtx) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { CHECK(!thr->slot); TidSlot* slot = nullptr; for (;;) { @@ -334,7 +334,7 @@ void SlotDetach(ThreadState* thr) { SlotDetachImpl(thr, true); } -void SlotLock(ThreadState* thr) NO_THREAD_SAFETY_ANALYSIS { +void SlotLock(ThreadState* thr) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { DCHECK(!thr->slot_locked); #if SANITIZER_DEBUG // Check these mutexes are not locked. @@ -756,7 +756,7 @@ int Finalize(ThreadState *thr) { } #if !SANITIZER_GO -void ForkBefore(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { +void ForkBefore(ThreadState* thr, uptr pc) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { GlobalProcessorLock(); // Detaching from the slot makes OnUserFree skip writing to the shadow. // The slot will be locked so any attempts to use it will deadlock anyway. @@ -783,7 +783,7 @@ void ForkBefore(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { __tsan_test_only_on_fork(); } -static void ForkAfter(ThreadState* thr) NO_THREAD_SAFETY_ANALYSIS { +static void ForkAfter(ThreadState* thr) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { thr->suppress_reports--; // Enabled in ForkBefore. thr->ignore_interceptors--; thr->ignore_reads_and_writes--; diff --git contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.h contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.h index d06358b462eb..fbf02806e34b 100644 --- contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -332,12 +332,12 @@ struct Context { Mutex slot_mtx; uptr global_epoch; // guarded by slot_mtx and by all slot mutexes bool resetting; // global reset is in progress - IList<TidSlot, &TidSlot::node> slot_queue GUARDED_BY(slot_mtx); + IList<TidSlot, &TidSlot::node> slot_queue SANITIZER_GUARDED_BY(slot_mtx); IList<TraceHeader, &TraceHeader::global, TracePart> trace_part_recycle - GUARDED_BY(slot_mtx); - uptr trace_part_total_allocated GUARDED_BY(slot_mtx); - uptr trace_part_recycle_finished GUARDED_BY(slot_mtx); - uptr trace_part_finished_excess GUARDED_BY(slot_mtx); + SANITIZER_GUARDED_BY(slot_mtx); + uptr trace_part_total_allocated SANITIZER_GUARDED_BY(slot_mtx); + uptr trace_part_recycle_finished SANITIZER_GUARDED_BY(slot_mtx); + uptr trace_part_finished_excess SANITIZER_GUARDED_BY(slot_mtx); }; extern Context *ctx; // The one and the only global runtime context. @@ -566,10 +566,10 @@ uptr ALWAYS_INLINE HeapEnd() { } #endif -void SlotAttachAndLock(ThreadState *thr) ACQUIRE(thr->slot->mtx); +void SlotAttachAndLock(ThreadState *thr) SANITIZER_ACQUIRE(thr->slot->mtx); void SlotDetach(ThreadState *thr); -void SlotLock(ThreadState *thr) ACQUIRE(thr->slot->mtx); -void SlotUnlock(ThreadState *thr) RELEASE(thr->slot->mtx); +void SlotLock(ThreadState *thr) SANITIZER_ACQUIRE(thr->slot->mtx); +void SlotUnlock(ThreadState *thr) SANITIZER_RELEASE(thr->slot->mtx); void DoReset(ThreadState *thr, uptr epoch); void FlushShadowMemory(); diff --git contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp index 940c20fcfa1a..e77bfba277a5 100644 --- contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp +++ contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp @@ -156,7 +156,7 @@ ALWAYS_INLINE void StoreShadow(RawShadow* sp, RawShadow s) { NOINLINE void DoReportRace(ThreadState* thr, RawShadow* shadow_mem, Shadow cur, Shadow old, - AccessType typ) NO_THREAD_SAFETY_ANALYSIS { + AccessType typ) SANITIZER_NO_THREAD_SAFETY_ANALYSIS { // For the free shadow markers the first element (that contains kFreeSid) // triggers the race, but the second element contains info about the freeing // thread, take it. diff --git contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_handlers_cxx.h contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_handlers_cxx.h index f7b9fc54f472..fd534c2573f6 100644 --- contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_handlers_cxx.h +++ contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_handlers_cxx.h @@ -51,4 +51,4 @@ __ubsan_handle_function_type_mismatch_v1_abort(FunctionTypeMismatchData *Data, ValueHandle fnRTTI); } -#endif // UBSAN_HANDLERS_H +#endif // UBSAN_HANDLERS_CXX_H diff --git contrib/llvm-project/libcxx/include/__algorithm/adjacent_find.h contrib/llvm-project/libcxx/include/__algorithm/adjacent_find.h index 621ef5f20f82..29ad83f96810 100644 --- contrib/llvm-project/libcxx/include/__algorithm/adjacent_find.h +++ contrib/llvm-project/libcxx/include/__algorithm/adjacent_find.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_ADJACENT_FIND_H #define _LIBCPP___ALGORITHM_ADJACENT_FIND_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/binary_search.h contrib/llvm-project/libcxx/include/__algorithm/binary_search.h index 8fc55b9becb1..2558dd0b27b9 100644 --- contrib/llvm-project/libcxx/include/__algorithm/binary_search.h +++ contrib/llvm-project/libcxx/include/__algorithm/binary_search.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_BINARY_SEARCH_H #define _LIBCPP___ALGORITHM_BINARY_SEARCH_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/lower_bound.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/clamp.h contrib/llvm-project/libcxx/include/__algorithm/clamp.h index db28735e97a3..a51c1015be3f 100644 --- contrib/llvm-project/libcxx/include/__algorithm/clamp.h +++ contrib/llvm-project/libcxx/include/__algorithm/clamp.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_CLAMP_H #define _LIBCPP___ALGORITHM_CLAMP_H +#include <__algorithm/comp.h> #include <__config> #include <__debug> -#include <__algorithm/comp.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__algorithm/copy.h contrib/llvm-project/libcxx/include/__algorithm/copy.h index e7e8b9e51a3e..65f0e0b0ef7d 100644 --- contrib/llvm-project/libcxx/include/__algorithm/copy.h +++ contrib/llvm-project/libcxx/include/__algorithm/copy.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_COPY_H #define _LIBCPP___ALGORITHM_COPY_H -#include <__config> #include <__algorithm/unwrap_iter.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <cstring> #include <type_traits> diff --git contrib/llvm-project/libcxx/include/__algorithm/copy_backward.h contrib/llvm-project/libcxx/include/__algorithm/copy_backward.h index 4a2f8c0c49cd..ac733290abe4 100644 --- contrib/llvm-project/libcxx/include/__algorithm/copy_backward.h +++ contrib/llvm-project/libcxx/include/__algorithm/copy_backward.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H #define _LIBCPP___ALGORITHM_COPY_BACKWARD_H -#include <__config> #include <__algorithm/unwrap_iter.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <cstring> #include <type_traits> diff --git contrib/llvm-project/libcxx/include/__algorithm/copy_if.h contrib/llvm-project/libcxx/include/__algorithm/copy_if.h index 230826f63af4..d32514d999b5 100644 --- contrib/llvm-project/libcxx/include/__algorithm/copy_if.h +++ contrib/llvm-project/libcxx/include/__algorithm/copy_if.h @@ -10,10 +10,6 @@ #define _LIBCPP___ALGORITHM_COPY_IF_H #include <__config> -#include <__algorithm/unwrap_iter.h> -#include <__iterator/iterator_traits.h> -#include <cstring> -#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__algorithm/copy_n.h contrib/llvm-project/libcxx/include/__algorithm/copy_n.h index 38a84a4105a4..cdcc0d50dbf1 100644 --- contrib/llvm-project/libcxx/include/__algorithm/copy_n.h +++ contrib/llvm-project/libcxx/include/__algorithm/copy_n.h @@ -9,11 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_COPY_N_H #define _LIBCPP___ALGORITHM_COPY_N_H -#include <__config> #include <__algorithm/copy.h> -#include <__algorithm/unwrap_iter.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <cstring> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/equal.h contrib/llvm-project/libcxx/include/__algorithm/equal.h index 0fe1a21fe526..4c9ad05ad6b8 100644 --- contrib/llvm-project/libcxx/include/__algorithm/equal.h +++ contrib/llvm-project/libcxx/include/__algorithm/equal.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_EQUAL_H #define _LIBCPP___ALGORITHM_EQUAL_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> diff --git contrib/llvm-project/libcxx/include/__algorithm/equal_range.h contrib/llvm-project/libcxx/include/__algorithm/equal_range.h index 679456e27b43..e13f0bdd9695 100644 --- contrib/llvm-project/libcxx/include/__algorithm/equal_range.h +++ contrib/llvm-project/libcxx/include/__algorithm/equal_range.h @@ -9,12 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_EQUAL_RANGE_H #define _LIBCPP___ALGORITHM_EQUAL_RANGE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/half_positive.h> #include <__algorithm/lower_bound.h> #include <__algorithm/upper_bound.h> +#include <__config> #include <iterator> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/fill.h contrib/llvm-project/libcxx/include/__algorithm/fill.h index 1fad1de993bf..0cb36b02c831 100644 --- contrib/llvm-project/libcxx/include/__algorithm/fill.h +++ contrib/llvm-project/libcxx/include/__algorithm/fill.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_FILL_H #define _LIBCPP___ALGORITHM_FILL_H -#include <__config> #include <__algorithm/fill_n.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <type_traits> diff --git contrib/llvm-project/libcxx/include/__algorithm/find_end.h contrib/llvm-project/libcxx/include/__algorithm/find_end.h index 5d971c57a4e0..dd0f7d7ac03d 100644 --- contrib/llvm-project/libcxx/include/__algorithm/find_end.h +++ contrib/llvm-project/libcxx/include/__algorithm/find_end.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_FIND_END_OF_H #define _LIBCPP___ALGORITHM_FIND_END_OF_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/find_first_of.h contrib/llvm-project/libcxx/include/__algorithm/find_first_of.h index 79a00acb9ee6..69354f61769f 100644 --- contrib/llvm-project/libcxx/include/__algorithm/find_first_of.h +++ contrib/llvm-project/libcxx/include/__algorithm/find_first_of.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_FIND_FIRST_OF_H #define _LIBCPP___ALGORITHM_FIND_FIRST_OF_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/in_in_result.h contrib/llvm-project/libcxx/include/__algorithm/in_in_result.h new file mode 100644 index 000000000000..fbe53ae4f57e --- /dev/null +++ contrib/llvm-project/libcxx/include/__algorithm/in_in_result.h @@ -0,0 +1,45 @@ +// -*- 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 _LIBCPP___ALGORITHM_IN_IN_RESULT_H +#define _LIBCPP___ALGORITHM_IN_IN_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_HAS_NO_RANGES + +namespace ranges { +template <class _I1, class _I2> +struct in_in_result { + [[no_unique_address]] _I1 in1; + [[no_unique_address]] _I2 in2; + + template <class _II1, class _II2> + requires convertible_to<const _I1&, _II1> && convertible_to<const _I2&, _II2> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_result<_II1, _II2>() const & { + return {in1, in2}; + } + + template <class _II1, class _II2> + requires convertible_to<_I1, _II1> && convertible_to<_I2, _II2> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_result<_II1, _II2>() && { return {_VSTD::move(in1), _VSTD::move(in2)}; } +}; +} // namespace ranges + +#endif // _LIBCPP_HAS_NO_RANGES + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_IN_RESULT_H diff --git contrib/llvm-project/libcxx/include/__algorithm/in_out_result.h contrib/llvm-project/libcxx/include/__algorithm/in_out_result.h new file mode 100644 index 000000000000..9d971157200f --- /dev/null +++ contrib/llvm-project/libcxx/include/__algorithm/in_out_result.h @@ -0,0 +1,52 @@ +// -*- 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 _LIBCPP___ALGORITHM_IN_OUT_RESULT_H +#define _LIBCPP___ALGORITHM_IN_OUT_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) +namespace ranges { + +template<class _InputIterator, class _OutputIterator> +struct in_out_result { + [[no_unique_address]] _InputIterator in; + [[no_unique_address]] _OutputIterator out; + + template <class _InputIterator2, class _OutputIterator2> + requires convertible_to<const _InputIterator&, _InputIterator2> && convertible_to<const _OutputIterator&, + _OutputIterator2> + _LIBCPP_HIDE_FROM_ABI + constexpr operator in_out_result<_InputIterator2, _OutputIterator2>() const & { + return {in, out}; + } + + template <class _InputIterator2, class _OutputIterator2> + requires convertible_to<_InputIterator, _InputIterator2> && convertible_to<_OutputIterator, _OutputIterator2> + _LIBCPP_HIDE_FROM_ABI + constexpr operator in_out_result<_InputIterator2, _OutputIterator2>() && { + return {_VSTD::move(in), _VSTD::move(out)}; + } +}; + +} // namespace ranges +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H diff --git contrib/llvm-project/libcxx/include/__algorithm/includes.h contrib/llvm-project/libcxx/include/__algorithm/includes.h index 9cc54d938dcf..9d0bc694c0d3 100644 --- contrib/llvm-project/libcxx/include/__algorithm/includes.h +++ contrib/llvm-project/libcxx/include/__algorithm/includes.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_INCLUDES_H #define _LIBCPP___ALGORITHM_INCLUDES_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/inplace_merge.h contrib/llvm-project/libcxx/include/__algorithm/inplace_merge.h index c74633a74cf3..e6f1efc011b1 100644 --- contrib/llvm-project/libcxx/include/__algorithm/inplace_merge.h +++ contrib/llvm-project/libcxx/include/__algorithm/inplace_merge.h @@ -9,14 +9,14 @@ #ifndef _LIBCPP___ALGORITHM_INPLACE_MERGE_H #define _LIBCPP___ALGORITHM_INPLACE_MERGE_H -#include <__config> -#include <__algorithm/comp_ref_type.h> #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> #include <__algorithm/lower_bound.h> #include <__algorithm/min.h> #include <__algorithm/move.h> #include <__algorithm/rotate.h> #include <__algorithm/upper_bound.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> #include <memory> diff --git contrib/llvm-project/libcxx/include/__algorithm/is_heap.h contrib/llvm-project/libcxx/include/__algorithm/is_heap.h index 22c27a66d129..925ba8bfb8bd 100644 --- contrib/llvm-project/libcxx/include/__algorithm/is_heap.h +++ contrib/llvm-project/libcxx/include/__algorithm/is_heap.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_IS_HEAP_H #define _LIBCPP___ALGORITHM_IS_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/is_heap_until.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/is_heap_until.h contrib/llvm-project/libcxx/include/__algorithm/is_heap_until.h index dd8a62f07fd3..aa23b6d039d3 100644 --- contrib/llvm-project/libcxx/include/__algorithm/is_heap_until.h +++ contrib/llvm-project/libcxx/include/__algorithm/is_heap_until.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H #define _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/is_sorted_until.h contrib/llvm-project/libcxx/include/__algorithm/is_sorted_until.h index 9a7f275c5400..57cad47761d9 100644 --- contrib/llvm-project/libcxx/include/__algorithm/is_sorted_until.h +++ contrib/llvm-project/libcxx/include/__algorithm/is_sorted_until.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H #define _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/lexicographical_compare.h contrib/llvm-project/libcxx/include/__algorithm/lexicographical_compare.h index a110a58c01c1..55a1da620125 100644 --- contrib/llvm-project/libcxx/include/__algorithm/lexicographical_compare.h +++ contrib/llvm-project/libcxx/include/__algorithm/lexicographical_compare.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H #define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/lower_bound.h contrib/llvm-project/libcxx/include/__algorithm/lower_bound.h index ddaecb045b3e..663a0b16228e 100644 --- contrib/llvm-project/libcxx/include/__algorithm/lower_bound.h +++ contrib/llvm-project/libcxx/include/__algorithm/lower_bound.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_LOWER_BOUND_H #define _LIBCPP___ALGORITHM_LOWER_BOUND_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/half_positive.h> +#include <__config> #include <iterator> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/make_heap.h contrib/llvm-project/libcxx/include/__algorithm/make_heap.h index b3defd4de072..f489addaf5cc 100644 --- contrib/llvm-project/libcxx/include/__algorithm/make_heap.h +++ contrib/llvm-project/libcxx/include/__algorithm/make_heap.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_MAKE_HEAP_H #define _LIBCPP___ALGORITHM_MAKE_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/sift_down.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -32,7 +32,7 @@ __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compar // start from the first parent, there is no need to consider children for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) { - _VSTD::__sift_down<_Compare>(__first, __last, __comp, __n, __first + __start); + _VSTD::__sift_down<_Compare>(__first, __comp, __n, __first + __start); } } } diff --git contrib/llvm-project/libcxx/include/__algorithm/max.h contrib/llvm-project/libcxx/include/__algorithm/max.h index 79cbd2be86b6..0bbc971e0a9c 100644 --- contrib/llvm-project/libcxx/include/__algorithm/max.h +++ contrib/llvm-project/libcxx/include/__algorithm/max.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_MAX_H #define _LIBCPP___ALGORITHM_MAX_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/max_element.h> +#include <__config> #include <initializer_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/max_element.h contrib/llvm-project/libcxx/include/__algorithm/max_element.h index f932ca7049fa..db2937260582 100644 --- contrib/llvm-project/libcxx/include/__algorithm/max_element.h +++ contrib/llvm-project/libcxx/include/__algorithm/max_element.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_MAX_ELEMENT_H #define _LIBCPP___ALGORITHM_MAX_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/merge.h contrib/llvm-project/libcxx/include/__algorithm/merge.h index 480380db6caa..91826493771a 100644 --- contrib/llvm-project/libcxx/include/__algorithm/merge.h +++ contrib/llvm-project/libcxx/include/__algorithm/merge.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_MERGE_H #define _LIBCPP___ALGORITHM_MERGE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/min.h contrib/llvm-project/libcxx/include/__algorithm/min.h index 5cacb2f28e7e..ed2d3b87828a 100644 --- contrib/llvm-project/libcxx/include/__algorithm/min.h +++ contrib/llvm-project/libcxx/include/__algorithm/min.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_MIN_H #define _LIBCPP___ALGORITHM_MIN_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/min_element.h> +#include <__config> #include <initializer_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/min_element.h contrib/llvm-project/libcxx/include/__algorithm/min_element.h index 3aebebca91ab..407c7f93336d 100644 --- contrib/llvm-project/libcxx/include/__algorithm/min_element.h +++ contrib/llvm-project/libcxx/include/__algorithm/min_element.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_MIN_ELEMENT_H #define _LIBCPP___ALGORITHM_MIN_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/minmax.h contrib/llvm-project/libcxx/include/__algorithm/minmax.h index a96a5b252c09..0bf88a70b8aa 100644 --- contrib/llvm-project/libcxx/include/__algorithm/minmax.h +++ contrib/llvm-project/libcxx/include/__algorithm/minmax.h @@ -9,12 +9,11 @@ #ifndef _LIBCPP___ALGORITHM_MINMAX_H #define _LIBCPP___ALGORITHM_MINMAX_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <initializer_list> #include <utility> - #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif diff --git contrib/llvm-project/libcxx/include/__algorithm/minmax_element.h contrib/llvm-project/libcxx/include/__algorithm/minmax_element.h index d21ff6f8dc5a..5d768603843b 100644 --- contrib/llvm-project/libcxx/include/__algorithm/minmax_element.h +++ contrib/llvm-project/libcxx/include/__algorithm/minmax_element.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H #define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <utility> diff --git contrib/llvm-project/libcxx/include/__algorithm/mismatch.h contrib/llvm-project/libcxx/include/__algorithm/mismatch.h index 7a01a985934a..230ade03df19 100644 --- contrib/llvm-project/libcxx/include/__algorithm/mismatch.h +++ contrib/llvm-project/libcxx/include/__algorithm/mismatch.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_MISMATCH_H #define _LIBCPP___ALGORITHM_MISMATCH_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <utility> diff --git contrib/llvm-project/libcxx/include/__algorithm/move.h contrib/llvm-project/libcxx/include/__algorithm/move.h index 7430bf087438..fa118f471669 100644 --- contrib/llvm-project/libcxx/include/__algorithm/move.h +++ contrib/llvm-project/libcxx/include/__algorithm/move.h @@ -9,12 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_MOVE_H #define _LIBCPP___ALGORITHM_MOVE_H -#include <__config> #include <__algorithm/unwrap_iter.h> +#include <__config> #include <__utility/move.h> #include <cstring> -#include <utility> #include <type_traits> +#include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__algorithm/move_backward.h contrib/llvm-project/libcxx/include/__algorithm/move_backward.h index ee72d39764ca..a4e3828b6069 100644 --- contrib/llvm-project/libcxx/include/__algorithm/move_backward.h +++ contrib/llvm-project/libcxx/include/__algorithm/move_backward.h @@ -9,11 +9,11 @@ #ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H #define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H -#include <__config> #include <__algorithm/unwrap_iter.h> +#include <__config> #include <cstring> -#include <utility> #include <type_traits> +#include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__algorithm/next_permutation.h contrib/llvm-project/libcxx/include/__algorithm/next_permutation.h index 1d71354eb375..eb81cceb7bbc 100644 --- contrib/llvm-project/libcxx/include/__algorithm/next_permutation.h +++ contrib/llvm-project/libcxx/include/__algorithm/next_permutation.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H #define _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/reverse.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> diff --git contrib/llvm-project/libcxx/include/__algorithm/nth_element.h contrib/llvm-project/libcxx/include/__algorithm/nth_element.h index 63feba1ea616..3afbd6c61846 100644 --- contrib/llvm-project/libcxx/include/__algorithm/nth_element.h +++ contrib/llvm-project/libcxx/include/__algorithm/nth_element.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_NTH_ELEMENT_H #define _LIBCPP___ALGORITHM_NTH_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/sort.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> diff --git contrib/llvm-project/libcxx/include/__algorithm/partial_sort.h contrib/llvm-project/libcxx/include/__algorithm/partial_sort.h index 622624ec4f42..a92a7e56610a 100644 --- contrib/llvm-project/libcxx/include/__algorithm/partial_sort.h +++ contrib/llvm-project/libcxx/include/__algorithm/partial_sort.h @@ -9,12 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_H #define _LIBCPP___ALGORITHM_PARTIAL_SORT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/make_heap.h> #include <__algorithm/sift_down.h> #include <__algorithm/sort_heap.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> @@ -31,8 +31,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Compare, class _RandomAccessIterator> _LIBCPP_CONSTEXPR_AFTER_CXX17 void __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, - _Compare __comp) + _Compare __comp) { + if (__first == __middle) + return; _VSTD::__make_heap<_Compare>(__first, __middle, __comp); typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; for (_RandomAccessIterator __i = __middle; __i != __last; ++__i) @@ -40,7 +42,7 @@ __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _R if (__comp(*__i, *__first)) { swap(*__i, *__first); - _VSTD::__sift_down<_Compare>(__first, __middle, __comp, __len, __first); + _VSTD::__sift_down<_Compare>(__first, __comp, __len, __first); } } _VSTD::__sort_heap<_Compare>(__first, __middle, __comp); @@ -64,7 +66,7 @@ void partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) { _VSTD::partial_sort(__first, __middle, __last, - __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); + __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); } _LIBCPP_END_NAMESPACE_STD diff --git contrib/llvm-project/libcxx/include/__algorithm/partial_sort_copy.h contrib/llvm-project/libcxx/include/__algorithm/partial_sort_copy.h index 4c0c9f5ad04a..67a62bae1f5a 100644 --- contrib/llvm-project/libcxx/include/__algorithm/partial_sort_copy.h +++ contrib/llvm-project/libcxx/include/__algorithm/partial_sort_copy.h @@ -9,14 +9,13 @@ #ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H #define _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/make_heap.h> #include <__algorithm/sift_down.h> #include <__algorithm/sort_heap.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <type_traits> // swap #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -40,7 +39,7 @@ __partial_sort_copy(_InputIterator __first, _InputIterator __last, if (__comp(*__first, *__result_first)) { *__result_first = *__first; - _VSTD::__sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first); + _VSTD::__sift_down<_Compare>(__result_first, __comp, __len, __result_first); } _VSTD::__sort_heap<_Compare>(__result_first, __r, __comp); } diff --git contrib/llvm-project/libcxx/include/__algorithm/partition.h contrib/llvm-project/libcxx/include/__algorithm/partition.h index 2614520ccbcf..131c5d3735d5 100644 --- contrib/llvm-project/libcxx/include/__algorithm/partition.h +++ contrib/llvm-project/libcxx/include/__algorithm/partition.h @@ -12,7 +12,6 @@ #include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> -#include <utility> // pair #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__algorithm/partition_point.h contrib/llvm-project/libcxx/include/__algorithm/partition_point.h index 33aaf33d938c..18e6e6f6812f 100644 --- contrib/llvm-project/libcxx/include/__algorithm/partition_point.h +++ contrib/llvm-project/libcxx/include/__algorithm/partition_point.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_PARTITION_POINT_H #define _LIBCPP___ALGORITHM_PARTITION_POINT_H -#include <__config> #include <__algorithm/half_positive.h> +#include <__config> #include <iterator> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/pop_heap.h contrib/llvm-project/libcxx/include/__algorithm/pop_heap.h index e8c801a5c81f..c1cc8016ac91 100644 --- contrib/llvm-project/libcxx/include/__algorithm/pop_heap.h +++ contrib/llvm-project/libcxx/include/__algorithm/pop_heap.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_POP_HEAP_H #define _LIBCPP___ALGORITHM_POP_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/sift_down.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> @@ -31,7 +31,7 @@ __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare if (__len > 1) { swap(*__first, *--__last); - _VSTD::__sift_down<_Compare>(__first, __last, __comp, __len - 1, __first); + _VSTD::__sift_down<_Compare>(__first, __comp, __len - 1, __first); } } diff --git contrib/llvm-project/libcxx/include/__algorithm/prev_permutation.h contrib/llvm-project/libcxx/include/__algorithm/prev_permutation.h index 12c1816da37e..457c2695b324 100644 --- contrib/llvm-project/libcxx/include/__algorithm/prev_permutation.h +++ contrib/llvm-project/libcxx/include/__algorithm/prev_permutation.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_PREV_PERMUTATION_H #define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/reverse.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> diff --git contrib/llvm-project/libcxx/include/__algorithm/push_heap.h contrib/llvm-project/libcxx/include/__algorithm/push_heap.h index 9327fe05b51d..864d419fa203 100644 --- contrib/llvm-project/libcxx/include/__algorithm/push_heap.h +++ contrib/llvm-project/libcxx/include/__algorithm/push_heap.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_PUSH_HEAP_H #define _LIBCPP___ALGORITHM_PUSH_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/move.h> diff --git contrib/llvm-project/libcxx/include/__algorithm/remove.h contrib/llvm-project/libcxx/include/__algorithm/remove.h index 171d83284a2e..681b9cc768d9 100644 --- contrib/llvm-project/libcxx/include/__algorithm/remove.h +++ contrib/llvm-project/libcxx/include/__algorithm/remove.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_REMOVE_H #define _LIBCPP___ALGORITHM_REMOVE_H -#include <__config> #include <__algorithm/find.h> #include <__algorithm/find_if.h> +#include <__config> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/remove_if.h contrib/llvm-project/libcxx/include/__algorithm/remove_if.h index 4df36896afd5..36f817cfa6e1 100644 --- contrib/llvm-project/libcxx/include/__algorithm/remove_if.h +++ contrib/llvm-project/libcxx/include/__algorithm/remove_if.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_REMOVE_IF_H #define _LIBCPP___ALGORITHM_REMOVE_IF_H -#include <__config> #include <__algorithm/find_if.h> +#include <__config> #include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/reverse.h contrib/llvm-project/libcxx/include/__algorithm/reverse.h index 28bd2e84c8ae..1198aeaf41f4 100644 --- contrib/llvm-project/libcxx/include/__algorithm/reverse.h +++ contrib/llvm-project/libcxx/include/__algorithm/reverse.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_REVERSE_H #define _LIBCPP___ALGORITHM_REVERSE_H -#include <__config> #include <__algorithm/iter_swap.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/rotate_copy.h contrib/llvm-project/libcxx/include/__algorithm/rotate_copy.h index 4c682ef93d5a..f9e644c88d0e 100644 --- contrib/llvm-project/libcxx/include/__algorithm/rotate_copy.h +++ contrib/llvm-project/libcxx/include/__algorithm/rotate_copy.h @@ -9,10 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_ROTATE_COPY_H #define _LIBCPP___ALGORITHM_ROTATE_COPY_H -#include <__config> #include <__algorithm/copy.h> -#include <iterator> -#include <type_traits> +#include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__algorithm/search_n.h contrib/llvm-project/libcxx/include/__algorithm/search_n.h index 67d066aa43d5..e4576cc76ac4 100644 --- contrib/llvm-project/libcxx/include/__algorithm/search_n.h +++ contrib/llvm-project/libcxx/include/__algorithm/search_n.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ALGORITHM_SEARCH_N_H #define _LIBCPP___ALGORITHM_SEARCH_N_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <type_traits> // __convert_to_integral diff --git contrib/llvm-project/libcxx/include/__algorithm/set_difference.h contrib/llvm-project/libcxx/include/__algorithm/set_difference.h index d4a9750d6dd7..00f61e070b4b 100644 --- contrib/llvm-project/libcxx/include/__algorithm/set_difference.h +++ contrib/llvm-project/libcxx/include/__algorithm/set_difference.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_SET_DIFFERENCE_H #define _LIBCPP___ALGORITHM_SET_DIFFERENCE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/set_intersection.h contrib/llvm-project/libcxx/include/__algorithm/set_intersection.h index 518e5e68b39d..f6aa38217d95 100644 --- contrib/llvm-project/libcxx/include/__algorithm/set_intersection.h +++ contrib/llvm-project/libcxx/include/__algorithm/set_intersection.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_SET_INTERSECTION_H #define _LIBCPP___ALGORITHM_SET_INTERSECTION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/set_symmetric_difference.h contrib/llvm-project/libcxx/include/__algorithm/set_symmetric_difference.h index efdf62725709..5b5c2acff773 100644 --- contrib/llvm-project/libcxx/include/__algorithm/set_symmetric_difference.h +++ contrib/llvm-project/libcxx/include/__algorithm/set_symmetric_difference.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H #define _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/set_union.h contrib/llvm-project/libcxx/include/__algorithm/set_union.h index 388f037a73a4..5b3e3af79b4f 100644 --- contrib/llvm-project/libcxx/include/__algorithm/set_union.h +++ contrib/llvm-project/libcxx/include/__algorithm/set_union.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_SET_UNION_H #define _LIBCPP___ALGORITHM_SET_UNION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/shift_left.h contrib/llvm-project/libcxx/include/__algorithm/shift_left.h index 8d9bc07d2e48..0466a3188a75 100644 --- contrib/llvm-project/libcxx/include/__algorithm/shift_left.h +++ contrib/llvm-project/libcxx/include/__algorithm/shift_left.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_SHIFT_LEFT_H #define _LIBCPP___ALGORITHM_SHIFT_LEFT_H -#include <__config> #include <__algorithm/move.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <type_traits> // swap +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__algorithm/shift_right.h contrib/llvm-project/libcxx/include/__algorithm/shift_right.h index cee17733a6a2..121712e85532 100644 --- contrib/llvm-project/libcxx/include/__algorithm/shift_right.h +++ contrib/llvm-project/libcxx/include/__algorithm/shift_right.h @@ -9,12 +9,13 @@ #ifndef _LIBCPP___ALGORITHM_SHIFT_RIGHT_H #define _LIBCPP___ALGORITHM_SHIFT_RIGHT_H -#include <__config> #include <__algorithm/move.h> #include <__algorithm/move_backward.h> #include <__algorithm/swap_ranges.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <type_traits> // swap +#include <__utility/swap.h> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__algorithm/sift_down.h contrib/llvm-project/libcxx/include/__algorithm/sift_down.h index 4d99ff237c96..bf5447698cd6 100644 --- contrib/llvm-project/libcxx/include/__algorithm/sift_down.h +++ contrib/llvm-project/libcxx/include/__algorithm/sift_down.h @@ -21,8 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Compare, class _RandomAccessIterator> _LIBCPP_CONSTEXPR_AFTER_CXX11 void -__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, - _Compare __comp, +__sift_down(_RandomAccessIterator __first, _Compare __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len, _RandomAccessIterator __start) { @@ -46,7 +45,7 @@ __sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, // check if we are in heap-order if (__comp(*__child_i, *__start)) - // we are, __start is larger than it's largest child + // we are, __start is larger than its largest child return; value_type __top(_VSTD::move(*__start)); diff --git contrib/llvm-project/libcxx/include/__algorithm/sort.h contrib/llvm-project/libcxx/include/__algorithm/sort.h index bc127689a674..5e09b280080a 100644 --- contrib/llvm-project/libcxx/include/__algorithm/sort.h +++ contrib/llvm-project/libcxx/include/__algorithm/sort.h @@ -9,12 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_SORT_H #define _LIBCPP___ALGORITHM_SORT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/min_element.h> #include <__algorithm/partial_sort.h> #include <__algorithm/unwrap_iter.h> +#include <__config> #include <__utility/swap.h> #include <memory> diff --git contrib/llvm-project/libcxx/include/__algorithm/sort_heap.h contrib/llvm-project/libcxx/include/__algorithm/sort_heap.h index bf6200c2a08d..64291ff2e8c9 100644 --- contrib/llvm-project/libcxx/include/__algorithm/sort_heap.h +++ contrib/llvm-project/libcxx/include/__algorithm/sort_heap.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_SORT_HEAP_H #define _LIBCPP___ALGORITHM_SORT_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/pop_heap.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <type_traits> // swap diff --git contrib/llvm-project/libcxx/include/__algorithm/stable_partition.h contrib/llvm-project/libcxx/include/__algorithm/stable_partition.h index 323b323c53dd..331f0fde77dc 100644 --- contrib/llvm-project/libcxx/include/__algorithm/stable_partition.h +++ contrib/llvm-project/libcxx/include/__algorithm/stable_partition.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_STABLE_PARTITION_H #define _LIBCPP___ALGORITHM_STABLE_PARTITION_H -#include <__config> #include <__algorithm/rotate.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> #include <memory> diff --git contrib/llvm-project/libcxx/include/__algorithm/stable_sort.h contrib/llvm-project/libcxx/include/__algorithm/stable_sort.h index 41e17bde99ef..4ae17e0e4d94 100644 --- contrib/llvm-project/libcxx/include/__algorithm/stable_sort.h +++ contrib/llvm-project/libcxx/include/__algorithm/stable_sort.h @@ -9,15 +9,15 @@ #ifndef _LIBCPP___ALGORITHM_STABLE_SORT_H #define _LIBCPP___ALGORITHM_STABLE_SORT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/inplace_merge.h> #include <__algorithm/sort.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> #include <memory> -#include <type_traits> // swap +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__algorithm/unique.h contrib/llvm-project/libcxx/include/__algorithm/unique.h index 62f0490b6d63..e17ff1567fa9 100644 --- contrib/llvm-project/libcxx/include/__algorithm/unique.h +++ contrib/llvm-project/libcxx/include/__algorithm/unique.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_UNIQUE_H #define _LIBCPP___ALGORITHM_UNIQUE_H -#include <__config> -#include <__algorithm/comp.h> #include <__algorithm/adjacent_find.h> +#include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/move.h> diff --git contrib/llvm-project/libcxx/include/__algorithm/unique_copy.h contrib/llvm-project/libcxx/include/__algorithm/unique_copy.h index 4c916dc3ada2..4833ae9b59f5 100644 --- contrib/llvm-project/libcxx/include/__algorithm/unique_copy.h +++ contrib/llvm-project/libcxx/include/__algorithm/unique_copy.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H #define _LIBCPP___ALGORITHM_UNIQUE_COPY_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <utility> diff --git contrib/llvm-project/libcxx/include/__algorithm/unwrap_iter.h contrib/llvm-project/libcxx/include/__algorithm/unwrap_iter.h index f77ecca6eee6..35765330bb7f 100644 --- contrib/llvm-project/libcxx/include/__algorithm/unwrap_iter.h +++ contrib/llvm-project/libcxx/include/__algorithm/unwrap_iter.h @@ -10,8 +10,8 @@ #define _LIBCPP___ALGORITHM_UNWRAP_ITER_H #include <__config> -#include <iterator> #include <__memory/pointer_traits.h> +#include <iterator> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__algorithm/upper_bound.h contrib/llvm-project/libcxx/include/__algorithm/upper_bound.h index 4ae7b8f9be1f..c064f1e35b9a 100644 --- contrib/llvm-project/libcxx/include/__algorithm/upper_bound.h +++ contrib/llvm-project/libcxx/include/__algorithm/upper_bound.h @@ -9,9 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_UPPER_BOUND_H #define _LIBCPP___ALGORITHM_UPPER_BOUND_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/half_positive.h> +#include <__config> #include <iterator> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__bit_reference contrib/llvm-project/libcxx/include/__bit_reference index a02492c077dd..a60a5c721907 100644 --- contrib/llvm-project/libcxx/include/__bit_reference +++ contrib/llvm-project/libcxx/include/__bit_reference @@ -10,8 +10,8 @@ #ifndef _LIBCPP___BIT_REFERENCE #define _LIBCPP___BIT_REFERENCE -#include <__config> #include <__bits> +#include <__config> #include <algorithm> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__chrono/calendar.h contrib/llvm-project/libcxx/include/__chrono/calendar.h new file mode 100644 index 000000000000..745f7f5cf529 --- /dev/null +++ contrib/llvm-project/libcxx/include/__chrono/calendar.h @@ -0,0 +1,1276 @@ +// -*- 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 _LIBCPP___CHRONO_CALENDAR_H +#define _LIBCPP___CHRONO_CALENDAR_H + +#include <__chrono/duration.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__config> +#include <limits> +#include <ratio> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +struct local_t {}; +template<class Duration> +using local_time = time_point<local_t, Duration>; +using local_seconds = local_time<seconds>; +using local_days = local_time<days>; + +struct last_spec { explicit last_spec() = default; }; + +class day { +private: + unsigned char __d; +public: + day() = default; + explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {} + inline constexpr day& operator++() noexcept { ++__d; return *this; } + inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } + inline constexpr day& operator--() noexcept { --__d; return *this; } + inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; } + constexpr day& operator+=(const days& __dd) noexcept; + constexpr day& operator-=(const days& __dd) noexcept; + explicit inline constexpr operator unsigned() const noexcept { return __d; } + inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; } + }; + + +inline constexpr +bool operator==(const day& __lhs, const day& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator!=(const day& __lhs, const day& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const day& __lhs, const day& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator> (const day& __lhs, const day& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const day& __lhs, const day& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const day& __lhs, const day& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +day operator+ (const day& __lhs, const days& __rhs) noexcept +{ return day(static_cast<unsigned>(__lhs) + __rhs.count()); } + +inline constexpr +day operator+ (const days& __lhs, const day& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +day operator- (const day& __lhs, const days& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +days operator-(const day& __lhs, const day& __rhs) noexcept +{ return days(static_cast<int>(static_cast<unsigned>(__lhs)) - + static_cast<int>(static_cast<unsigned>(__rhs))); } + +inline constexpr day& day::operator+=(const days& __dd) noexcept +{ *this = *this + __dd; return *this; } + +inline constexpr day& day::operator-=(const days& __dd) noexcept +{ *this = *this - __dd; return *this; } + + +class month { +private: + unsigned char __m; +public: + month() = default; + explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {} + inline constexpr month& operator++() noexcept { ++__m; return *this; } + inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } + inline constexpr month& operator--() noexcept { --__m; return *this; } + inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } + constexpr month& operator+=(const months& __m1) noexcept; + constexpr month& operator-=(const months& __m1) noexcept; + explicit inline constexpr operator unsigned() const noexcept { return __m; } + inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; } +}; + + +inline constexpr +bool operator==(const month& __lhs, const month& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator!=(const month& __lhs, const month& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const month& __lhs, const month& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator> (const month& __lhs, const month& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const month& __lhs, const month& __rhs) noexcept +{ return !(__rhs < __lhs); } + +inline constexpr +bool operator>=(const month& __lhs, const month& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +month operator+ (const month& __lhs, const months& __rhs) noexcept +{ + auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1); + auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; + return month{static_cast<unsigned>(__mu - __yr * 12 + 1)}; +} + +inline constexpr +month operator+ (const months& __lhs, const month& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +month operator- (const month& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +months operator-(const month& __lhs, const month& __rhs) noexcept +{ + auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs); + return months(__dm <= 11 ? __dm : __dm + 12); +} + +inline constexpr month& month::operator+=(const months& __dm) noexcept +{ *this = *this + __dm; return *this; } + +inline constexpr month& month::operator-=(const months& __dm) noexcept +{ *this = *this - __dm; return *this; } + + +class year { +private: + short __y; +public: + year() = default; + explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {} + + inline constexpr year& operator++() noexcept { ++__y; return *this; } + inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; } + inline constexpr year& operator--() noexcept { --__y; return *this; } + inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; } + constexpr year& operator+=(const years& __dy) noexcept; + constexpr year& operator-=(const years& __dy) noexcept; + inline constexpr year operator+() const noexcept { return *this; } + inline constexpr year operator-() const noexcept { return year{-__y}; } + + inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); } + explicit inline constexpr operator int() const noexcept { return __y; } + constexpr bool ok() const noexcept; + static inline constexpr year min() noexcept { return year{-32767}; } + static inline constexpr year max() noexcept { return year{ 32767}; } +}; + + +inline constexpr +bool operator==(const year& __lhs, const year& __rhs) noexcept +{ return static_cast<int>(__lhs) == static_cast<int>(__rhs); } + +inline constexpr +bool operator!=(const year& __lhs, const year& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year& __lhs, const year& __rhs) noexcept +{ return static_cast<int>(__lhs) < static_cast<int>(__rhs); } + +inline constexpr +bool operator> (const year& __lhs, const year& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year& __lhs, const year& __rhs) noexcept +{ return !(__rhs < __lhs); } + +inline constexpr +bool operator>=(const year& __lhs, const year& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +year operator+ (const year& __lhs, const years& __rhs) noexcept +{ return year(static_cast<int>(__lhs) + __rhs.count()); } + +inline constexpr +year operator+ (const years& __lhs, const year& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year operator- (const year& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +years operator-(const year& __lhs, const year& __rhs) noexcept +{ return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; } + + +inline constexpr year& year::operator+=(const years& __dy) noexcept +{ *this = *this + __dy; return *this; } + +inline constexpr year& year::operator-=(const years& __dy) noexcept +{ *this = *this - __dy; return *this; } + +inline constexpr bool year::ok() const noexcept +{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); } + +class weekday_indexed; +class weekday_last; + +class weekday { +private: + unsigned char __wd; + static constexpr unsigned char __weekday_from_days(int __days) noexcept; +public: + weekday() = default; + inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {} + inline constexpr weekday(const sys_days& __sysd) noexcept + : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {} + inline explicit constexpr weekday(const local_days& __locd) noexcept + : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {} + + inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; } + inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } + inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; } + inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } + constexpr weekday& operator+=(const days& __dd) noexcept; + constexpr weekday& operator-=(const days& __dd) noexcept; + inline constexpr unsigned c_encoding() const noexcept { return __wd; } + inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; } + inline constexpr bool ok() const noexcept { return __wd <= 6; } + constexpr weekday_indexed operator[](unsigned __index) const noexcept; + constexpr weekday_last operator[](last_spec) const noexcept; +}; + + +// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days +inline constexpr +unsigned char weekday::__weekday_from_days(int __days) noexcept +{ + return static_cast<unsigned char>( + static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) + ); +} + +inline constexpr +bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept +{ return __lhs.c_encoding() == __rhs.c_encoding(); } + +inline constexpr +bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept +{ return __lhs.c_encoding() < __rhs.c_encoding(); } + +inline constexpr +bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__lhs < __rhs); } + +constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept +{ + auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count(); + auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; + return weekday{static_cast<unsigned>(__mu - __yr * 7)}; +} + +constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept +{ return __lhs + -__rhs; } + +constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept +{ + const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); + const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; + return days{__wdu - __wk * 7}; +} + +inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept +{ *this = *this + __dd; return *this; } + +inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept +{ *this = *this - __dd; return *this; } + + +class weekday_indexed { +private: + chrono::weekday __wd; + unsigned char __idx; +public: + weekday_indexed() = default; + inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept + : __wd{__wdval}, __idx(__idxval) {} + inline constexpr chrono::weekday weekday() const noexcept { return __wd; } + inline constexpr unsigned index() const noexcept { return __idx; } + inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; } +}; + +inline constexpr +bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept +{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } + +inline constexpr +bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +class weekday_last { +private: + chrono::weekday __wd; +public: + explicit constexpr weekday_last(const chrono::weekday& __val) noexcept + : __wd{__val} {} + constexpr chrono::weekday weekday() const noexcept { return __wd; } + constexpr bool ok() const noexcept { return __wd.ok(); } +}; + +inline constexpr +bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept +{ return __lhs.weekday() == __rhs.weekday(); } + +inline constexpr +bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } + +inline constexpr +weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } + + +inline constexpr last_spec last{}; +inline constexpr weekday Sunday{0}; +inline constexpr weekday Monday{1}; +inline constexpr weekday Tuesday{2}; +inline constexpr weekday Wednesday{3}; +inline constexpr weekday Thursday{4}; +inline constexpr weekday Friday{5}; +inline constexpr weekday Saturday{6}; + +inline constexpr month January{1}; +inline constexpr month February{2}; +inline constexpr month March{3}; +inline constexpr month April{4}; +inline constexpr month May{5}; +inline constexpr month June{6}; +inline constexpr month July{7}; +inline constexpr month August{8}; +inline constexpr month September{9}; +inline constexpr month October{10}; +inline constexpr month November{11}; +inline constexpr month December{12}; + + +class month_day { +private: + chrono::month __m; + chrono::day __d; +public: + month_day() = default; + constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept + : __m{__mval}, __d{__dval} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::day day() const noexcept { return __d; } + constexpr bool ok() const noexcept; +}; + +inline constexpr +bool month_day::ok() const noexcept +{ + if (!__m.ok()) return false; + const unsigned __dval = static_cast<unsigned>(__d); + if (__dval < 1 || __dval > 31) return false; + if (__dval <= 29) return true; +// Now we've got either 30 or 31 + const unsigned __mval = static_cast<unsigned>(__m); + if (__mval == 2) return false; + if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) + return __dval == 30; + return true; +} + +inline constexpr +bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } + +inline constexpr +bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +month_day operator/(const month& __lhs, const day& __rhs) noexcept +{ return month_day{__lhs, __rhs}; } + +constexpr +month_day operator/(const day& __lhs, const month& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +month_day operator/(const month& __lhs, int __rhs) noexcept +{ return __lhs / day(__rhs); } + +constexpr +month_day operator/(int __lhs, const day& __rhs) noexcept +{ return month(__lhs) / __rhs; } + +constexpr +month_day operator/(const day& __lhs, int __rhs) noexcept +{ return month(__rhs) / __lhs; } + + +inline constexpr +bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept +{ return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); } + +inline constexpr +bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept +{ return !(__lhs < __rhs); } + + + +class month_day_last { +private: + chrono::month __m; +public: + explicit constexpr month_day_last(const chrono::month& __val) noexcept + : __m{__val} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr bool ok() const noexcept { return __m.ok(); } +}; + +inline constexpr +bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __lhs.month() == __rhs.month(); } + +inline constexpr +bool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __lhs.month() < __rhs.month(); } + +inline constexpr +bool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +month_day_last operator/(const month& __lhs, last_spec) noexcept +{ return month_day_last{__lhs}; } + +inline constexpr +month_day_last operator/(last_spec, const month& __rhs) noexcept +{ return month_day_last{__rhs}; } + +inline constexpr +month_day_last operator/(int __lhs, last_spec) noexcept +{ return month_day_last{month(__lhs)}; } + +inline constexpr +month_day_last operator/(last_spec, int __rhs) noexcept +{ return month_day_last{month(__rhs)}; } + + +class month_weekday { +private: + chrono::month __m; + chrono::weekday_indexed __wdi; +public: + constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept + : __m{__mval}, __wdi{__wdival} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } + inline constexpr bool ok() const noexcept { return __m.ok() && __wdi.ok(); } +}; + +inline constexpr +bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } + +inline constexpr +bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept +{ return month_weekday{__lhs, __rhs}; } + +inline constexpr +month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept +{ return month_weekday{month(__lhs), __rhs}; } + +inline constexpr +month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept +{ return month_weekday{__rhs, __lhs}; } + +inline constexpr +month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept +{ return month_weekday{month(__rhs), __lhs}; } + + +class month_weekday_last { + chrono::month __m; + chrono::weekday_last __wdl; + public: + constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept + : __m{__mval}, __wdl{__wdlval} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } + inline constexpr bool ok() const noexcept { return __m.ok() && __wdl.ok(); } +}; + +inline constexpr +bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } + +inline constexpr +bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +inline constexpr +month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept +{ return month_weekday_last{__lhs, __rhs}; } + +inline constexpr +month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept +{ return month_weekday_last{month(__lhs), __rhs}; } + +inline constexpr +month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept +{ return month_weekday_last{__rhs, __lhs}; } + +inline constexpr +month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept +{ return month_weekday_last{month(__rhs), __lhs}; } + + +class year_month { + chrono::year __y; + chrono::month __m; +public: + year_month() = default; + constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept + : __y{__yval}, __m{__mval} {} + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; } + inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; } + inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; } + inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; } + inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); } +}; + +inline constexpr +year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; } + +inline constexpr +year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; } + +inline constexpr +bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); } + +inline constexpr +bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept +{ return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); } + +inline constexpr +bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept +{ return !(__lhs < __rhs); } + +constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept +{ + int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count(); + const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12; + __dmi = __dmi - __dy * 12 + 1; + return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi)); +} + +constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept +{ return __rhs + __lhs; } + +constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept +{ return (__lhs.year() + __rhs) / __lhs.month(); } + +constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept +{ return __rhs + __lhs; } + +constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept +{ return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); } + +constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +class year_month_day_last; + +class year_month_day { +private: + chrono::year __y; + chrono::month __m; + chrono::day __d; +public: + year_month_day() = default; + inline constexpr year_month_day( + const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept + : __y{__yval}, __m{__mval}, __d{__dval} {} + constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; + inline constexpr year_month_day(const sys_days& __sysd) noexcept + : year_month_day(__from_days(__sysd.time_since_epoch())) {} + inline explicit constexpr year_month_day(const local_days& __locd) noexcept + : year_month_day(__from_days(__locd.time_since_epoch())) {} + + constexpr year_month_day& operator+=(const months& __dm) noexcept; + constexpr year_month_day& operator-=(const months& __dm) noexcept; + constexpr year_month_day& operator+=(const years& __dy) noexcept; + constexpr year_month_day& operator-=(const years& __dy) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::day day() const noexcept { return __d; } + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + + constexpr bool ok() const noexcept; + + static constexpr year_month_day __from_days(days __d) noexcept; + constexpr days __to_days() const noexcept; +}; + + +// https://howardhinnant.github.io/date_algorithms.html#civil_from_days +inline constexpr +year_month_day +year_month_day::__from_days(days __d) noexcept +{ + static_assert(numeric_limits<unsigned>::digits >= 18, ""); + static_assert(numeric_limits<int>::digits >= 20 , ""); + const int __z = __d.count() + 719468; + const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; + const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096] + const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] + const int __yr = static_cast<int>(__yoe) + __era * 400; + const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] + const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] + const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] + const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] + return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; +} + +// https://howardhinnant.github.io/date_algorithms.html#days_from_civil +inline constexpr days year_month_day::__to_days() const noexcept +{ + static_assert(numeric_limits<unsigned>::digits >= 18, ""); + static_assert(numeric_limits<int>::digits >= 20 , ""); + + const int __yr = static_cast<int>(__y) - (__m <= February); + const unsigned __mth = static_cast<unsigned>(__m); + const unsigned __dy = static_cast<unsigned>(__d); + + const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; + const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399] + const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] + const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] + return days{__era * 146097 + static_cast<int>(__doe) - 719468}; +} + +inline constexpr +bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } + +inline constexpr +bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ + if (__lhs.year() < __rhs.year()) return true; + if (__lhs.year() > __rhs.year()) return false; + if (__lhs.month() < __rhs.month()) return true; + if (__lhs.month() > __rhs.month()) return false; + return __lhs.day() < __rhs.day(); +} + +inline constexpr +bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept +{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; } + +inline constexpr +year_month_day operator/(const year_month& __lhs, int __rhs) noexcept +{ return __lhs / day(__rhs); } + +inline constexpr +year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept +{ return __lhs / __rhs.month() / __rhs.day(); } + +inline constexpr +year_month_day operator/(int __lhs, const month_day& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +inline constexpr +year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +year_month_day operator/(const month_day& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +inline constexpr +year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept +{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); } + +inline constexpr +year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept +{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); } + +inline constexpr +year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +class year_month_day_last { +private: + chrono::year __y; + chrono::month_day_last __mdl; +public: + constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept + : __y{__yval}, __mdl{__mdlval} {} + + constexpr year_month_day_last& operator+=(const months& __m) noexcept; + constexpr year_month_day_last& operator-=(const months& __m) noexcept; + constexpr year_month_day_last& operator+=(const years& __y) noexcept; + constexpr year_month_day_last& operator-=(const years& __y) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __mdl.month(); } + inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; } + constexpr chrono::day day() const noexcept; + inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } + inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); } +}; + +inline constexpr +chrono::day year_month_day_last::day() const noexcept +{ + constexpr chrono::day __d[] = + { + chrono::day(31), chrono::day(28), chrono::day(31), + chrono::day(30), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(30), chrono::day(31) + }; + return (month() != February || !__y.is_leap()) && month().ok() ? + __d[static_cast<unsigned>(month()) - 1] : chrono::day{29}; +} + +inline constexpr +bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } + +inline constexpr +bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ + if (__lhs.year() < __rhs.year()) return true; + if (__lhs.year() > __rhs.year()) return false; + return __lhs.month_day_last() < __rhs.month_day_last(); +} + +inline constexpr +bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept +{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; } + +inline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept +{ return year_month_day_last{__lhs, __rhs}; } + +inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept +{ return year_month_day_last{year{__lhs}, __rhs}; } + +inline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept +{ return year{__rhs} / __lhs; } + + +inline constexpr +year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / last; } + +inline constexpr +year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr +year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept +{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; } + +inline constexpr +year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept + : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {} + +inline constexpr bool year_month_day::ok() const noexcept +{ + if (!__y.ok() || !__m.ok()) return false; + return chrono::day{1} <= __d && __d <= (__y / __m / last).day(); +} + +class year_month_weekday { + chrono::year __y; + chrono::month __m; + chrono::weekday_indexed __wdi; +public: + year_month_weekday() = default; + constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, + const chrono::weekday_indexed& __wdival) noexcept + : __y{__yval}, __m{__mval}, __wdi{__wdival} {} + constexpr year_month_weekday(const sys_days& __sysd) noexcept + : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} + inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept + : year_month_weekday(__from_days(__locd.time_since_epoch())) {} + constexpr year_month_weekday& operator+=(const months& m) noexcept; + constexpr year_month_weekday& operator-=(const months& m) noexcept; + constexpr year_month_weekday& operator+=(const years& y) noexcept; + constexpr year_month_weekday& operator-=(const years& y) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday weekday() const noexcept { return __wdi.weekday(); } + inline constexpr unsigned index() const noexcept { return __wdi.index(); } + inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } + + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + inline constexpr bool ok() const noexcept + { + if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false; + if (__wdi.index() <= 4) return true; + auto __nth_weekday_day = + __wdi.weekday() - + chrono::weekday{static_cast<sys_days>(__y / __m / 1)} + + days{(__wdi.index() - 1) * 7 + 1}; + return static_cast<unsigned>(__nth_weekday_day.count()) <= + static_cast<unsigned>((__y / __m / last).day()); + } + + static constexpr year_month_weekday __from_days(days __d) noexcept; + constexpr days __to_days() const noexcept; +}; + +inline constexpr +year_month_weekday year_month_weekday::__from_days(days __d) noexcept +{ + const sys_days __sysd{__d}; + const chrono::weekday __wd = chrono::weekday(__sysd); + const year_month_day __ymd = year_month_day(__sysd); + return year_month_weekday{__ymd.year(), __ymd.month(), + __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]}; +} + +inline constexpr +days year_month_weekday::__to_days() const noexcept +{ + const sys_days __sysd = sys_days(__y/__m/1); + return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7})) + .time_since_epoch(); +} + +inline constexpr +bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } + +inline constexpr +bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept +{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } + +inline constexpr +year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept +{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; } + +inline constexpr +year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +inline constexpr +year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +inline constexpr +year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); } + +inline constexpr +year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr +year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept +{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; } + +inline constexpr +year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + + +inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +class year_month_weekday_last { +private: + chrono::year __y; + chrono::month __m; + chrono::weekday_last __wdl; +public: + constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval, + const chrono::weekday_last& __wdlval) noexcept + : __y{__yval}, __m{__mval}, __wdl{__wdlval} {} + constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; + constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; + constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; + constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); } + inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); } + + constexpr days __to_days() const noexcept; + +}; + +inline constexpr +days year_month_weekday_last::__to_days() const noexcept +{ + const sys_days __last = sys_days{__y/__m/last}; + return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch(); + +} + +inline constexpr +bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } + +inline constexpr +bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +inline constexpr +year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept +{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } + +inline constexpr +year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept +{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; } + +inline constexpr +year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +inline constexpr +year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +inline constexpr +year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); } + +inline constexpr +year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr +year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept +{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; } + +inline constexpr +year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + + +template <class _Duration> +class hh_mm_ss +{ +private: + static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); + using __CommonType = common_type_t<_Duration, chrono::seconds>; + + static constexpr uint64_t __pow10(unsigned __exp) + { + uint64_t __ret = 1; + for (unsigned __i = 0; __i < __exp; ++__i) + __ret *= 10U; + return __ret; + } + + static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) + { + if (__n >= 2 && __d != 0 && __w < 19) + return 1 + __width(__n, __d % __n * 10, __w+1); + return 0; + } + +public: + static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ? + __width(__CommonType::period::den) : 6u; + using precision = duration<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>; + + constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} + + constexpr explicit hh_mm_ss(_Duration __d) noexcept : + __is_neg(__d < _Duration(0)), + __h(duration_cast<chrono::hours> (abs(__d))), + __m(duration_cast<chrono::minutes>(abs(__d) - hours())), + __s(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())), + __f(duration_cast<precision> (abs(__d) - hours() - minutes() - seconds())) + {} + + constexpr bool is_negative() const noexcept { return __is_neg; } + constexpr chrono::hours hours() const noexcept { return __h; } + constexpr chrono::minutes minutes() const noexcept { return __m; } + constexpr chrono::seconds seconds() const noexcept { return __s; } + constexpr precision subseconds() const noexcept { return __f; } + + constexpr precision to_duration() const noexcept + { + auto __dur = __h + __m + __s + __f; + return __is_neg ? -__dur : __dur; + } + + constexpr explicit operator precision() const noexcept { return to_duration(); } + +private: + bool __is_neg; + chrono::hours __h; + chrono::minutes __m; + chrono::seconds __s; + precision __f; +}; + +constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } +constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } + +constexpr hours make12(const hours& __h) noexcept +{ + if (__h == hours( 0)) return hours(12); + else if (__h <= hours(12)) return __h; + else return __h - hours(12); +} + +constexpr hours make24(const hours& __h, bool __is_pm) noexcept +{ + if (__is_pm) + return __h == hours(12) ? __h : __h + hours(12); + else + return __h == hours(12) ? hours(0) : __h; +} + +} // namespace chrono + +inline namespace literals +{ + inline namespace chrono_literals + { + constexpr chrono::day operator ""d(unsigned long long __d) noexcept + { + return chrono::day(static_cast<unsigned>(__d)); + } + + constexpr chrono::year operator ""y(unsigned long long __y) noexcept + { + return chrono::year(static_cast<int>(__y)); + } +} // namespace chrono_literals +} // namespace literals + +namespace chrono { // hoist the literals into namespace std::chrono + using namespace literals::chrono_literals; +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_CALENDAR_H diff --git contrib/llvm-project/libcxx/include/__chrono/convert_to_timespec.h contrib/llvm-project/libcxx/include/__chrono/convert_to_timespec.h new file mode 100644 index 000000000000..0106e6dec3e1 --- /dev/null +++ contrib/llvm-project/libcxx/include/__chrono/convert_to_timespec.h @@ -0,0 +1,55 @@ +// -*- 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 _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H +#define _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H + +#include <__chrono/duration.h> +#include <__config> +#include <limits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Convert a nanoseconds duration to the given TimeSpec type, which must have +// the same properties as std::timespec. +template <class _TimeSpec> +_LIBCPP_HIDE_FROM_ABI inline +_TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns) +{ + using namespace chrono; + seconds __s = duration_cast<seconds>(__ns); + _TimeSpec __ts; + typedef decltype(__ts.tv_sec) __ts_sec; + const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); + + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = 999999999; // (10^9 - 1) + } + + return __ts; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H diff --git contrib/llvm-project/libcxx/include/__chrono/duration.h contrib/llvm-project/libcxx/include/__chrono/duration.h new file mode 100644 index 000000000000..24801772ec5d --- /dev/null +++ contrib/llvm-project/libcxx/include/__chrono/duration.h @@ -0,0 +1,615 @@ +// -*- 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 _LIBCPP___CHRONO_DURATION_H +#define _LIBCPP___CHRONO_DURATION_H + +#include <__config> +#include <limits> +#include <ratio> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template <class _Rep, class _Period = ratio<1> > class _LIBCPP_TEMPLATE_VIS duration; + +template <class _Tp> +struct __is_duration : false_type {}; + +template <class _Rep, class _Period> +struct __is_duration<duration<_Rep, _Period> > : true_type {}; + +template <class _Rep, class _Period> +struct __is_duration<const duration<_Rep, _Period> > : true_type {}; + +template <class _Rep, class _Period> +struct __is_duration<volatile duration<_Rep, _Period> > : true_type {}; + +template <class _Rep, class _Period> +struct __is_duration<const volatile duration<_Rep, _Period> > : true_type {}; + +} // namespace chrono + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +struct _LIBCPP_TEMPLATE_VIS common_type<chrono::duration<_Rep1, _Period1>, + chrono::duration<_Rep2, _Period2> > +{ + typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type, + typename __ratio_gcd<_Period1, _Period2>::type> type; +}; + +namespace chrono { + +// duration_cast + +template <class _FromDuration, class _ToDuration, + class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type, + bool = _Period::num == 1, + bool = _Period::den == 1> +struct __duration_cast; + +template <class _FromDuration, class _ToDuration, class _Period> +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count())); + } +}; + +template <class _FromDuration, class _ToDuration, class _Period> +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; + return _ToDuration(static_cast<typename _ToDuration::rep>( + static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); + } +}; + +template <class _FromDuration, class _ToDuration, class _Period> +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; + return _ToDuration(static_cast<typename _ToDuration::rep>( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); + } +}; + +template <class _FromDuration, class _ToDuration, class _Period> +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; + return _ToDuration(static_cast<typename _ToDuration::rep>( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) + / static_cast<_Ct>(_Period::den))); + } +}; + +template <class _ToDuration, class _Rep, class _Period> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +duration_cast(const duration<_Rep, _Period>& __fd) +{ + return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd); +} + +template <class _Rep> +struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {}; + +#if _LIBCPP_STD_VER > 14 +template <class _Rep> +inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; +#endif + +template <class _Rep> +struct _LIBCPP_TEMPLATE_VIS duration_values +{ +public: + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} +}; + +#if _LIBCPP_STD_VER > 14 +template <class _ToDuration, class _Rep, class _Period> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +floor(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = duration_cast<_ToDuration>(__d); + if (__t > __d) + __t = __t - _ToDuration{1}; + return __t; +} + +template <class _ToDuration, class _Rep, class _Period> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +ceil(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = duration_cast<_ToDuration>(__d); + if (__t < __d) + __t = __t + _ToDuration{1}; + return __t; +} + +template <class _ToDuration, class _Rep, class _Period> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +round(const duration<_Rep, _Period>& __d) +{ + _ToDuration __lower = floor<_ToDuration>(__d); + _ToDuration __upper = __lower + _ToDuration{1}; + auto __lowerDiff = __d - __lower; + auto __upperDiff = __upper - __d; + if (__lowerDiff < __upperDiff) + return __lower; + if (__lowerDiff > __upperDiff) + return __upper; + return __lower.count() & 1 ? __upper : __lower; +} +#endif + +// duration + +template <class _Rep, class _Period> +class _LIBCPP_TEMPLATE_VIS duration +{ + static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); + static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); + static_assert(_Period::num > 0, "duration period must be positive"); + + template <class _R1, class _R2> + struct __no_overflow + { + private: + static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; + static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; + static const intmax_t __n1 = _R1::num / __gcd_n1_n2; + static const intmax_t __d1 = _R1::den / __gcd_d1_d2; + static const intmax_t __n2 = _R2::num / __gcd_n1_n2; + static const intmax_t __d2 = _R2::den / __gcd_d1_d2; + static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); + + template <intmax_t _Xp, intmax_t _Yp, bool __overflow> + struct __mul // __overflow == false + { + static const intmax_t value = _Xp * _Yp; + }; + + template <intmax_t _Xp, intmax_t _Yp> + struct __mul<_Xp, _Yp, true> + { + static const intmax_t value = 1; + }; + + public: + static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); + typedef ratio<__mul<__n1, __d2, !value>::value, + __mul<__n2, __d1, !value>::value> type; + }; + +public: + typedef _Rep rep; + typedef typename _Period::type period; +private: + rep __rep_; +public: + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +#ifndef _LIBCPP_CXX03_LANG + duration() = default; +#else + duration() {} +#endif + + template <class _Rep2> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + explicit duration(const _Rep2& __r, + typename enable_if + < + is_convertible<_Rep2, rep>::value && + (treat_as_floating_point<rep>::value || + !treat_as_floating_point<_Rep2>::value) + >::type* = nullptr) + : __rep_(__r) {} + + // conversions + template <class _Rep2, class _Period2> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + duration(const duration<_Rep2, _Period2>& __d, + typename enable_if + < + __no_overflow<_Period2, period>::value && ( + treat_as_floating_point<rep>::value || + (__no_overflow<_Period2, period>::type::den == 1 && + !treat_as_floating_point<_Rep2>::value)) + >::type* = nullptr) + : __rep_(chrono::duration_cast<duration>(__d).count()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {return typename common_type<duration>::type(*this);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {return typename common_type<duration>::type(-__rep_);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator++() {++__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator++(int) {return duration(__rep_++);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator--() {--__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator--(int) {return duration(__rep_--);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values<rep>::zero());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values<rep>::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values<rep>::max());} +}; + +typedef duration<long long, nano> nanoseconds; +typedef duration<long long, micro> microseconds; +typedef duration<long long, milli> milliseconds; +typedef duration<long long > seconds; +typedef duration< long, ratio< 60> > minutes; +typedef duration< long, ratio<3600> > hours; +#if _LIBCPP_STD_VER > 17 +typedef duration< int, ratio_multiply<ratio<24>, hours::period>> days; +typedef duration< int, ratio_multiply<ratio<7>, days::period>> weeks; +typedef duration< int, ratio_multiply<ratio<146097, 400>, days::period>> years; +typedef duration< int, ratio_divide<years::period, ratio<12>>> months; +#endif +// Duration == + +template <class _LhsDuration, class _RhsDuration> +struct __duration_eq +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() == _Ct(__rhs).count(); + } +}; + +template <class _LhsDuration> +struct __duration_eq<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() == __rhs.count();} +}; + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration != + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// Duration < + +template <class _LhsDuration, class _RhsDuration> +struct __duration_lt +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() < _Ct(__rhs).count(); + } +}; + +template <class _LhsDuration> +struct __duration_lt<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() < __rhs.count();} +}; + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration > + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __rhs < __lhs; +} + +// Duration <= + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// Duration >= + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// Duration + + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type +operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); +} + +// Duration - + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type +operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); +} + +// Duration * + +template <class _Rep1, class _Period, class _Rep2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration<typename common_type<_Rep1, _Rep2>::type, _Period> +>::type +operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); +} + +template <class _Rep1, class _Period, class _Rep2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value, + duration<typename common_type<_Rep1, _Rep2>::type, _Period> +>::type +operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) +{ + return __d * __s; +} + +// Duration / + +template <class _Rep1, class _Period, class _Rep2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + !__is_duration<_Rep2>::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration<typename common_type<_Rep1, _Rep2>::type, _Period> +>::type +operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); +} + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<_Rep1, _Rep2>::type +operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct; + return _Ct(__lhs).count() / _Ct(__rhs).count(); +} + +// Duration % + +template <class _Rep1, class _Period, class _Rep2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + !__is_duration<_Rep2>::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration<typename common_type<_Rep1, _Rep2>::type, _Period> +>::type +operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); +} + +template <class _Rep1, class _Period1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type +operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); +} + +} // namespace chrono + +#if _LIBCPP_STD_VER > 11 +// Suffixes for duration literals [time.duration.literals] +inline namespace literals +{ + inline namespace chrono_literals + { + + constexpr chrono::hours operator""h(unsigned long long __h) + { + return chrono::hours(static_cast<chrono::hours::rep>(__h)); + } + + constexpr chrono::duration<long double, ratio<3600,1>> operator""h(long double __h) + { + return chrono::duration<long double, ratio<3600,1>>(__h); + } + + + constexpr chrono::minutes operator""min(unsigned long long __m) + { + return chrono::minutes(static_cast<chrono::minutes::rep>(__m)); + } + + constexpr chrono::duration<long double, ratio<60,1>> operator""min(long double __m) + { + return chrono::duration<long double, ratio<60,1>> (__m); + } + + + constexpr chrono::seconds operator""s(unsigned long long __s) + { + return chrono::seconds(static_cast<chrono::seconds::rep>(__s)); + } + + constexpr chrono::duration<long double> operator""s(long double __s) + { + return chrono::duration<long double> (__s); + } + + + constexpr chrono::milliseconds operator""ms(unsigned long long __ms) + { + return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms)); + } + + constexpr chrono::duration<long double, milli> operator""ms(long double __ms) + { + return chrono::duration<long double, milli>(__ms); + } + + + constexpr chrono::microseconds operator""us(unsigned long long __us) + { + return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us)); + } + + constexpr chrono::duration<long double, micro> operator""us(long double __us) + { + return chrono::duration<long double, micro> (__us); + } + + + constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) + { + return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns)); + } + + constexpr chrono::duration<long double, nano> operator""ns(long double __ns) + { + return chrono::duration<long double, nano> (__ns); + } + +} // namespace chrono_literals +} // namespace literals + +namespace chrono { // hoist the literals into namespace std::chrono + using namespace literals::chrono_literals; +} // namespace chrono + +#endif // _LIBCPP_STD_VER > 11 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_DURATION_H diff --git contrib/llvm-project/libcxx/include/__chrono/file_clock.h contrib/llvm-project/libcxx/include/__chrono/file_clock.h new file mode 100644 index 000000000000..cd8758f81908 --- /dev/null +++ contrib/llvm-project/libcxx/include/__chrono/file_clock.h @@ -0,0 +1,85 @@ +// -*- 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 _LIBCPP___CHRONO_FILE_CLOCK_H +#define _LIBCPP___CHRONO_FILE_CLOCK_H + +#include <__availability> +#include <__chrono/duration.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__config> +#include <ratio> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +// [time.clock.file], type file_clock +using file_clock = _VSTD_FS::_FilesystemClock; + +template<class _Duration> +using file_time = time_point<file_clock, _Duration>; + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock { +#if !defined(_LIBCPP_HAS_NO_INT128) + typedef __int128_t rep; + typedef nano period; +#else + typedef long long rep; + typedef nano period; +#endif + + typedef chrono::duration<rep, period> duration; + typedef chrono::time_point<_FilesystemClock> time_point; + + _LIBCPP_EXPORTED_FROM_ABI + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; + + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept; + +#if _LIBCPP_STD_VER > 17 + template <class _Duration> + _LIBCPP_HIDE_FROM_ABI + static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { + return chrono::sys_time<_Duration>(__t.time_since_epoch()); + } + + template <class _Duration> + _LIBCPP_HIDE_FROM_ABI + static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { + return chrono::file_time<_Duration>(__t.time_since_epoch()); + } +#endif // _LIBCPP_STD_VER > 17 +}; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + +#endif // _LIBCPP___CHRONO_FILE_CLOCK_H diff --git contrib/llvm-project/libcxx/include/__chrono/high_resolution_clock.h contrib/llvm-project/libcxx/include/__chrono/high_resolution_clock.h new file mode 100644 index 000000000000..f5cde4acb979 --- /dev/null +++ contrib/llvm-project/libcxx/include/__chrono/high_resolution_clock.h @@ -0,0 +1,36 @@ +// -*- 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 _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H +#define _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H + +#include <__chrono/steady_clock.h> +#include <__chrono/system_clock.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +typedef steady_clock high_resolution_clock; +#else +typedef system_clock high_resolution_clock; +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H diff --git contrib/llvm-project/libcxx/include/__chrono/steady_clock.h contrib/llvm-project/libcxx/include/__chrono/steady_clock.h new file mode 100644 index 000000000000..5ba911df843e --- /dev/null +++ contrib/llvm-project/libcxx/include/__chrono/steady_clock.h @@ -0,0 +1,44 @@ +// -*- 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 _LIBCPP___CHRONO_STEADY_CLOCK_H +#define _LIBCPP___CHRONO_STEADY_CLOCK_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +class _LIBCPP_TYPE_VIS steady_clock +{ +public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<steady_clock, duration> time_point; + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true; + + static time_point now() _NOEXCEPT; +}; +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_STEADY_CLOCK_H diff --git contrib/llvm-project/libcxx/include/__chrono/system_clock.h contrib/llvm-project/libcxx/include/__chrono/system_clock.h new file mode 100644 index 000000000000..9c977d369e1b --- /dev/null +++ contrib/llvm-project/libcxx/include/__chrono/system_clock.h @@ -0,0 +1,54 @@ +// -*- 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 _LIBCPP___CHRONO_SYSTEM_CLOCK_H +#define _LIBCPP___CHRONO_SYSTEM_CLOCK_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> +#include <ctime> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class _LIBCPP_TYPE_VIS system_clock +{ +public: + typedef microseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point<system_clock> time_point; + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; + + static time_point now() _NOEXCEPT; + static time_t to_time_t (const time_point& __t) _NOEXCEPT; + static time_point from_time_t(time_t __t) _NOEXCEPT; +}; + +#if _LIBCPP_STD_VER > 17 + +template <class _Duration> +using sys_time = time_point<system_clock, _Duration>; +using sys_seconds = sys_time<seconds>; +using sys_days = sys_time<days>; + +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_SYSTEM_CLOCK_H diff --git contrib/llvm-project/libcxx/include/__chrono/time_point.h contrib/llvm-project/libcxx/include/__chrono/time_point.h new file mode 100644 index 000000000000..c042e125145a --- /dev/null +++ contrib/llvm-project/libcxx/include/__chrono/time_point.h @@ -0,0 +1,249 @@ +// -*- 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 _LIBCPP___CHRONO_TIME_POINT_H +#define _LIBCPP___CHRONO_TIME_POINT_H + +#include <__chrono/duration.h> +#include <__config> +#include <limits> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template <class _Clock, class _Duration = typename _Clock::duration> +class _LIBCPP_TEMPLATE_VIS time_point +{ + static_assert(__is_duration<_Duration>::value, + "Second template parameter of time_point must be a std::chrono::duration"); +public: + typedef _Clock clock; + typedef _Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; +private: + duration __d_; + +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {} + + // conversions + template <class _Duration2> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + time_point(const time_point<clock, _Duration2>& t, + typename enable_if + < + is_convertible<_Duration2, duration>::value + >::type* = nullptr) + : __d_(t.time_since_epoch()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());} +}; + +} // namespace chrono + +template <class _Clock, class _Duration1, class _Duration2> +struct _LIBCPP_TEMPLATE_VIS common_type<chrono::time_point<_Clock, _Duration1>, + chrono::time_point<_Clock, _Duration2> > +{ + typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; +}; + +namespace chrono { + +template <class _ToDuration, class _Clock, class _Duration> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, _ToDuration> +time_point_cast(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); +} + +#if _LIBCPP_STD_VER > 14 +template <class _ToDuration, class _Clock, class _Duration> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +floor(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{floor<_ToDuration>(__t.time_since_epoch())}; +} + +template <class _ToDuration, class _Clock, class _Duration> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +ceil(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{ceil<_ToDuration>(__t.time_since_epoch())}; +} + +template <class _ToDuration, class _Clock, class _Duration> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +round(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{round<_ToDuration>(__t.time_since_epoch())}; +} + +template <class _Rep, class _Period> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + numeric_limits<_Rep>::is_signed, + duration<_Rep, _Period> +>::type +abs(duration<_Rep, _Period> __d) +{ + return __d >= __d.zero() ? +__d : -__d; +} +#endif // _LIBCPP_STD_VER > 14 + +// time_point == + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() == __rhs.time_since_epoch(); +} + +// time_point != + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// time_point < + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() < __rhs.time_since_epoch(); +} + +// time_point > + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs < __lhs; +} + +// time_point <= + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// time_point >= + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// time_point operator+(time_point x, duration y); + +template <class _Clock, class _Duration1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; + return _Tr (__lhs.time_since_epoch() + __rhs); +} + +// time_point operator+(duration x, time_point y); + +template <class _Rep1, class _Period1, class _Clock, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type> +operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs + __lhs; +} + +// time_point operator-(time_point x, duration y); + +template <class _Clock, class _Duration1, class _Rep2, class _Period2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; + return _Ret(__lhs.time_since_epoch() -__rhs); +} + +// duration operator-(time_point x, time_point y); + +template <class _Clock, class _Duration1, class _Duration2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename common_type<_Duration1, _Duration2>::type +operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() - __rhs.time_since_epoch(); +} + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_TIME_POINT_H diff --git contrib/llvm-project/libcxx/include/__compare/compare_three_way.h contrib/llvm-project/libcxx/include/__compare/compare_three_way.h index 3edddf1a1c94..d7f339eda992 100644 --- contrib/llvm-project/libcxx/include/__compare/compare_three_way.h +++ contrib/llvm-project/libcxx/include/__compare/compare_three_way.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___COMPARE_COMPARE_THREE_WAY_H #define _LIBCPP___COMPARE_COMPARE_THREE_WAY_H -#include <__config> #include <__compare/three_way_comparable.h> +#include <__config> #include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__compare/synth_three_way.h contrib/llvm-project/libcxx/include/__compare/synth_three_way.h index 3d8e738816dd..0f302c0fa11f 100644 --- contrib/llvm-project/libcxx/include/__compare/synth_three_way.h +++ contrib/llvm-project/libcxx/include/__compare/synth_three_way.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___COMPARE_SYNTH_THREE_WAY_H #define _LIBCPP___COMPARE_SYNTH_THREE_WAY_H -#include <__config> #include <__compare/ordering.h> #include <__compare/three_way_comparable.h> #include <__concepts/boolean_testable.h> +#include <__config> #include <__utility/declval.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__concepts/class_or_enum.h contrib/llvm-project/libcxx/include/__concepts/class_or_enum.h index 43c7636d9c81..aa8606a21929 100644 --- contrib/llvm-project/libcxx/include/__concepts/class_or_enum.h +++ contrib/llvm-project/libcxx/include/__concepts/class_or_enum.h @@ -25,6 +25,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _Tp> concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; +// Work around Clang bug https://llvm.org/PR52970 +template<class _Tp> +concept __workaround_52970 = is_class_v<__uncvref_t<_Tp>> || is_union_v<__uncvref_t<_Tp>>; + #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) _LIBCPP_END_NAMESPACE_STD diff --git contrib/llvm-project/libcxx/include/__concepts/convertible_to.h contrib/llvm-project/libcxx/include/__concepts/convertible_to.h index ec68967106d5..795b0bd7494c 100644 --- contrib/llvm-project/libcxx/include/__concepts/convertible_to.h +++ contrib/llvm-project/libcxx/include/__concepts/convertible_to.h @@ -10,6 +10,7 @@ #define _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H #include <__config> +#include <__utility/declval.h> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -25,8 +26,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _From, class _To> concept convertible_to = is_convertible_v<_From, _To> && - requires (add_rvalue_reference_t<_From> (&__f)()) { - static_cast<_To>(__f()); + requires { + static_cast<_To>(declval<_From>()); }; #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) diff --git contrib/llvm-project/libcxx/include/__config contrib/llvm-project/libcxx/include/__config index 720e12eac0dd..b99cdc38dc9f 100644 --- contrib/llvm-project/libcxx/include/__config +++ contrib/llvm-project/libcxx/include/__config @@ -107,6 +107,15 @@ # define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI // Enable clang::trivial_abi on std::shared_ptr and std::weak_ptr # define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI +// std::random_device holds some state when it uses an implementation that gets +// entropy from a file (see _LIBCPP_USING_DEV_RANDOM). When switching from this +// implementation to another one on a platform that has already shipped +// std::random_device, one needs to retain the same object layout to remain ABI +// compatible. This switch removes these workarounds for platforms that don't care +// about ABI compatibility. +# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT +// Remove basic_string common base +# define _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS #elif _LIBCPP_ABI_VERSION == 1 # if !defined(_LIBCPP_OBJECT_FORMAT_COFF) // Enable compiling copies of now inline methods into the dylib to support @@ -250,6 +259,10 @@ # endif // defined(__GLIBC_PREREQ) #endif // defined(__linux__) +#if defined(__MVS__) +# include <features.h> // for __NATIVE_ASCII_F +#endif + #ifdef __LITTLE_ENDIAN__ # if __LITTLE_ENDIAN__ # define _LIBCPP_LITTLE_ENDIAN @@ -354,6 +367,12 @@ // When this option is used, the token passed to `std::random_device`'s // constructor *must* be "/dev/urandom" -- anything else is an error. // +// _LIBCPP_USING_FUCHSIA_CPRNG +// Use Fuchsia's zx_cprng_draw() system call, which is specified to +// deliver high-quality entropy and cannot fail. +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +// // _LIBCPP_USING_NACL_RANDOM // NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access, // including accesses to the special files under `/dev`. This implementation @@ -365,10 +384,12 @@ // Use rand_s(), for use on Windows. // When this option is used, the token passed to `std::random_device`'s // constructor *must* be "/dev/urandom" -- anything else is an error. -#if defined(__OpenBSD__) +#if defined(__OpenBSD__) || defined(__APPLE__) # define _LIBCPP_USING_ARC4_RANDOM -#elif defined(__Fuchsia__) || defined(__wasi__) +#elif defined(__wasi__) # define _LIBCPP_USING_GETENTROPY +#elif defined(__Fuchsia__) +# define _LIBCPP_USING_FUCHSIA_CPRNG #elif defined(__native_client__) # define _LIBCPP_USING_NACL_RANDOM #elif defined(_LIBCPP_WIN32API) @@ -1204,9 +1225,9 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container( # define _LIBCPP_C_HAS_NO_GETS #endif -#if defined(__BIONIC__) || defined(__NuttX__) || \ - defined(__Fuchsia__) || defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) || \ - defined(__MVS__) || defined(__OpenBSD__) +#if defined(__BIONIC__) || defined(__NuttX__) || \ + defined(__Fuchsia__) || defined(__wasi__) || \ + defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) #define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE #endif diff --git contrib/llvm-project/libcxx/include/__coroutine/noop_coroutine_handle.h contrib/llvm-project/libcxx/include/__coroutine/noop_coroutine_handle.h index 9dbf21aac5e6..a29e202f4e4f 100644 --- contrib/llvm-project/libcxx/include/__coroutine/noop_coroutine_handle.h +++ contrib/llvm-project/libcxx/include/__coroutine/noop_coroutine_handle.h @@ -20,7 +20,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__builtin_coro_noop) +#if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) + // [coroutine.noop] // [coroutine.promise.noop] struct noop_coroutine_promise {}; @@ -64,20 +65,45 @@ private: _LIBCPP_HIDE_FROM_ABI friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept; +#if __has_builtin(__builtin_coro_noop) _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { this->__handle_ = __builtin_coro_noop(); } void* __handle_ = nullptr; + +#elif defined(_LIBCPP_COMPILER_GCC) + // GCC doesn't implement __builtin_coro_noop(). + // Construct the coroutine frame manually instead. + struct __noop_coroutine_frame_ty_ { + static void __dummy_resume_destroy_func() { } + + void (*__resume_)() = __dummy_resume_destroy_func; + void (*__destroy_)() = __dummy_resume_destroy_func; + struct noop_coroutine_promise __promise_; + }; + + static __noop_coroutine_frame_ty_ __noop_coroutine_frame_; + + void* __handle_ = &__noop_coroutine_frame_; + + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default; + +#endif // __has_builtin(__builtin_coro_noop) }; using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>; +#if defined(_LIBCPP_COMPILER_GCC) +inline noop_coroutine_handle::__noop_coroutine_frame_ty_ + noop_coroutine_handle::__noop_coroutine_frame_{}; +#endif + // [coroutine.noop.coroutine] inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } -#endif // __has_builtin(__builtin_coro_noop) +#endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) _LIBCPP_END_NAMESPACE_STD diff --git contrib/llvm-project/libcxx/include/__debug contrib/llvm-project/libcxx/include/__debug index 42f6cef4c07f..a1e21a703224 100644 --- contrib/llvm-project/libcxx/include/__debug +++ contrib/llvm-project/libcxx/include/__debug @@ -12,6 +12,7 @@ #include <__config> #include <iosfwd> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -22,9 +23,9 @@ #endif #if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) -# include <cstdlib> -# include <cstdio> # include <cstddef> +# include <cstdio> +# include <cstdlib> #endif #if _LIBCPP_DEBUG_LEVEL == 0 @@ -268,6 +269,26 @@ _LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); #endif // _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY) +template <class _Tp> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_insert_c(_Tp* __c) { +#if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) + __get_db()->__insert_c(__c); +#else + (void)(__c); +#endif +} + +template <class _Tp> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_insert_i(_Tp* __i) { +#if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) + __get_db()->__insert_i(__i); +#else + (void)(__i); +#endif +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_DEBUG_H diff --git contrib/llvm-project/libcxx/include/__filesystem/directory_entry.h contrib/llvm-project/libcxx/include/__filesystem/directory_entry.h index 9efe19465428..91dd1a214588 100644 --- contrib/llvm-project/libcxx/include/__filesystem/directory_entry.h +++ contrib/llvm-project/libcxx/include/__filesystem/directory_entry.h @@ -12,17 +12,18 @@ #include <__availability> #include <__config> -#include <__filesystem/path.h> -#include <__filesystem/file_time_type.h> -#include <__filesystem/filesystem_error.h> +#include <__errc> #include <__filesystem/file_status.h> +#include <__filesystem/file_time_type.h> #include <__filesystem/file_type.h> +#include <__filesystem/filesystem_error.h> #include <__filesystem/operations.h> +#include <__filesystem/path.h> #include <__filesystem/perms.h> -#include <__errc> #include <chrono> #include <cstdint> #include <cstdlib> +#include <iosfwd> #include <system_error> _LIBCPP_PUSH_MACROS @@ -239,6 +240,12 @@ public: return __p_ >= __rhs.__p_; } + template <class _CharT, class _Traits> + _LIBCPP_INLINE_VISIBILITY + friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { + return __os << __d.path(); + } + private: friend class directory_iterator; friend class recursive_directory_iterator; diff --git contrib/llvm-project/libcxx/include/__filesystem/directory_iterator.h contrib/llvm-project/libcxx/include/__filesystem/directory_iterator.h index be958e0eb8de..7ea66bbc7ff0 100644 --- contrib/llvm-project/libcxx/include/__filesystem/directory_iterator.h +++ contrib/llvm-project/libcxx/include/__filesystem/directory_iterator.h @@ -12,12 +12,12 @@ #include <__availability> #include <__config> +#include <__debug> #include <__filesystem/directory_entry.h> #include <__filesystem/directory_options.h> #include <__filesystem/path.h> #include <__iterator/iterator_traits.h> #include <__memory/shared_ptr.h> -#include <__debug> #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> #include <cstddef> diff --git contrib/llvm-project/libcxx/include/__filesystem/filesystem_error.h contrib/llvm-project/libcxx/include/__filesystem/filesystem_error.h index a8c6977b48e9..0b1874b0e50e 100644 --- contrib/llvm-project/libcxx/include/__filesystem/filesystem_error.h +++ contrib/llvm-project/libcxx/include/__filesystem/filesystem_error.h @@ -14,9 +14,9 @@ #include <__config> #include <__filesystem/path.h> #include <__memory/shared_ptr.h> -#include <system_error> #include <iosfwd> #include <new> +#include <system_error> #include <type_traits> #ifndef _LIBCPP_CXX03_LANG diff --git contrib/llvm-project/libcxx/include/__filesystem/operations.h contrib/llvm-project/libcxx/include/__filesystem/operations.h index 19d6c2d437f9..918b4f9362e6 100644 --- contrib/llvm-project/libcxx/include/__filesystem/operations.h +++ contrib/llvm-project/libcxx/include/__filesystem/operations.h @@ -30,430 +30,118 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH -_LIBCPP_FUNC_VIS -path __absolute(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -path __canonical(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -bool __copy_file(const path& __from, const path& __to, copy_options __opt, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -void __copy(const path& __from, const path& __to, copy_options __opt, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -bool __create_directories(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -void __create_directory_symlink(const path& __to, const path& __new_symlink, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -bool __create_directory(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -bool __create_directory(const path& p, const path& attributes, - error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -void __create_hard_link(const path& __to, const path& __new_hard_link, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -void __create_symlink(const path& __to, const path& __new_symlink, - error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -path __current_path(error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -void __current_path(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -bool __equivalent(const path&, const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -file_status __status(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -uintmax_t __file_size(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -file_status __symlink_status(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -file_time_type __last_write_time(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -void __last_write_time(const path& p, file_time_type new_time, - error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -path __weakly_canonical(path const& __p, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS -path __read_symlink(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -uintmax_t __remove_all(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -bool __remove(const path& p, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -void __rename(const path& from, const path& to, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr); -_LIBCPP_FUNC_VIS -path __temp_directory_path(error_code* __ec = nullptr); - -inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) { - return __absolute(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p, - error_code& __ec) { - return __absolute(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) { - return __canonical(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p, - error_code& __ec) { - return __canonical(__p, &__ec); -} - - -inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, - const path& __to) { - return __copy_file(__from, __to, copy_options::none); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -copy_file(const path& __from, const path& __to, error_code& __ec) { - return __copy_file(__from, __to, copy_options::none, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -copy_file(const path& __from, const path& __to, copy_options __opt) { - return __copy_file(__from, __to, __opt); -} - -inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, - const path& __to, - copy_options __opt, - error_code& __ec) { - return __copy_file(__from, __to, __opt, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing, - const path& __new) { - __copy_symlink(__existing, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY void -copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept { - __copy_symlink(__ext, __new, &__ec); -} - - -inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, - const path& __to) { - __copy(__from, __to, copy_options::none); -} - -inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, - error_code& __ec) { - __copy(__from, __to, copy_options::none, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, - copy_options __opt) { - __copy(__from, __to, __opt); -} - -inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, - copy_options __opt, - error_code& __ec) { - __copy(__from, __to, __opt, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) { - return __create_directories(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p, - error_code& __ec) { - return __create_directories(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void -create_directory_symlink(const path& __to, const path& __new) { - __create_directory_symlink(__to, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY void -create_directory_symlink(const path& __to, const path& __new, - error_code& __ec) noexcept { - __create_directory_symlink(__to, __new, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) { - return __create_directory(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -create_directory(const path& __p, error_code& __ec) noexcept { - return __create_directory(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, - const path& __attrs) { - return __create_directory(__p, __attrs); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -create_directory(const path& __p, const path& __attrs, - error_code& __ec) noexcept { - return __create_directory(__p, __attrs, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to, - const path& __new) { - __create_hard_link(__to, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY void -create_hard_link(const path& __to, const path& __new, - error_code& __ec) noexcept { - __create_hard_link(__to, __new, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to, - const path& __new) { - __create_symlink(__to, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY void -create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept { - return __create_symlink(__to, __new, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path current_path() { - return __current_path(); -} - -inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) { - return __current_path(&__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) { - __current_path(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p, - error_code& __ec) noexcept { - __current_path(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, - const path& __p2) { - return __equivalent(__p1, __p2); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { - return __equivalent(__p1, __p2, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept { - return __s.type() != file_type::none; -} - -inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept { - return status_known(__s) && __s.type() != file_type::not_found; -} - -inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) { - return exists(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, - error_code& __ec) noexcept { +_LIBCPP_FUNC_VIS path __absolute(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __canonical(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directories(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directory(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directory(const path& p, const path& attributes, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __current_path(error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __current_path(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __equivalent(const path&, const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_status __status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __file_size(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_status __symlink_status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_time_type __last_write_time(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __last_write_time(const path& p, file_time_type new_time, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __read_symlink(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __remove_all(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS bool __remove(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __rename(const path& from, const path& to, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS path __temp_directory_path(error_code* __ec = nullptr); + +inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) { return __absolute(__p); } +inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p) { return __canonical(__p); } +inline _LIBCPP_INLINE_VISIBILITY path canonical(const path& __p, error_code& __ec) { return __canonical(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to) { return __copy_file(__from, __to, copy_options::none); } +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to, error_code& __ec) { return __copy_file(__from, __to, copy_options::none, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to, copy_options __opt) { return __copy_file(__from, __to, __opt); } +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { return __copy_file(__from, __to, __opt, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __from, const path& __to) { __copy_symlink(__from, __to); } +inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __from, const path& __to, error_code& __ec) noexcept { __copy_symlink(__from, __to, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to) { __copy(__from, __to, copy_options::none); } +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, error_code& __ec) { __copy(__from, __to, copy_options::none, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, copy_options __opt) { __copy(__from, __to, __opt); } +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { __copy(__from, __to, __opt, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) { return __create_directories(__p); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p, error_code& __ec) { return __create_directories(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void create_directory_symlink(const path& __target, const path& __link) { __create_directory_symlink(__target, __link); } +inline _LIBCPP_INLINE_VISIBILITY void create_directory_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { __create_directory_symlink(__target, __link, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) { return __create_directory(__p); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, error_code& __ec) noexcept { return __create_directory(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, const path& __attrs) { return __create_directory(__p, __attrs); } +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, const path& __attrs, error_code& __ec) noexcept { return __create_directory(__p, __attrs, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __target, const path& __link) { __create_hard_link(__target, __link); } +inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __target, const path& __link, error_code& __ec) noexcept { __create_hard_link(__target, __link, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __target, const path& __link) { __create_symlink(__target, __link); } +inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { return __create_symlink(__target, __link, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY path current_path() { return __current_path(); } +inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) { return __current_path(&__ec); } +inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) { __current_path(__p); } +inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p, error_code& __ec) noexcept { __current_path(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, const path& __p2) { return __equivalent(__p1, __p2); } +inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { return __equivalent(__p1, __p2, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; } +inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept { return status_known(__s) && __s.type() != file_type::not_found; } +inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) { return exists(__status(__p)); } + +inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, error_code& __ec) noexcept { auto __s = __status(__p, &__ec); if (status_known(__s)) __ec.clear(); return exists(__s); } -inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) { - return __file_size(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY uintmax_t -file_size(const path& __p, error_code& __ec) noexcept { - return __file_size(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) { - return __hard_link_count(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY uintmax_t -hard_link_count(const path& __p, error_code& __ec) noexcept { - return __hard_link_count(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept { - return __s.type() == file_type::block; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) { - return is_block_file(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p, - error_code& __ec) noexcept { - return is_block_file(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -is_character_file(file_status __s) noexcept { - return __s.type() == file_type::character; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) { - return is_character_file(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -is_character_file(const path& __p, error_code& __ec) noexcept { - return is_character_file(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept { - return __s.type() == file_type::directory; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) { - return is_directory(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p, - error_code& __ec) noexcept { - return is_directory(__status(__p, &__ec)); -} - -_LIBCPP_FUNC_VIS -bool __fs_is_empty(const path& p, error_code* ec = nullptr); - -inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) { - return __fs_is_empty(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p, - error_code& __ec) { - return __fs_is_empty(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept { - return __s.type() == file_type::fifo; -} -inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) { - return is_fifo(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p, - error_code& __ec) noexcept { - return is_fifo(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -is_regular_file(file_status __s) noexcept { - return __s.type() == file_type::regular; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) { - return is_regular_file(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool -is_regular_file(const path& __p, error_code& __ec) noexcept { - return is_regular_file(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept { - return __s.type() == file_type::symlink; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) { - return is_symlink(__symlink_status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p, - error_code& __ec) noexcept { - return is_symlink(__symlink_status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept { - return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && - !is_symlink(__s); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) { - return is_other(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p, - error_code& __ec) noexcept { - return is_other(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept { - return __s.type() == file_type::socket; -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) { - return is_socket(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p, - error_code& __ec) noexcept { - return is_socket(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY file_time_type -last_write_time(const path& __p) { - return __last_write_time(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY file_time_type -last_write_time(const path& __p, error_code& __ec) noexcept { - return __last_write_time(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, - file_time_type __t) { - __last_write_time(__p, __t); -} - -inline _LIBCPP_INLINE_VISIBILITY void -last_write_time(const path& __p, file_time_type __t, - error_code& __ec) noexcept { - __last_write_time(__p, __t, &__ec); -} - -_LIBCPP_FUNC_VIS -void __permissions(const path&, perms, perm_options, error_code* = nullptr); - -inline _LIBCPP_INLINE_VISIBILITY void -permissions(const path& __p, perms __prms, - perm_options __opts = perm_options::replace) { - __permissions(__p, __prms, __opts); -} - -inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, - error_code& __ec) noexcept { - __permissions(__p, __prms, perm_options::replace, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, - perm_options __opts, - error_code& __ec) { - __permissions(__p, __prms, __opts, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, - const path& __base, - error_code& __ec) { +inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) { return __file_size(__p); } +inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p, error_code& __ec) noexcept { return __file_size(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); } +inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept { return __hard_link_count(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; } +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) { return is_block_file(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p, error_code& __ec) noexcept { return is_block_file(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(file_status __s) noexcept { return __s.type() == file_type::character; } +inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) { return is_character_file(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p, error_code& __ec) noexcept { return is_character_file(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; } +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) { return is_directory(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); } +_LIBCPP_FUNC_VIS bool __fs_is_empty(const path& p, error_code* ec = nullptr); +inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) { return __fs_is_empty(__p); } +inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; } +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) { return is_fifo(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p, error_code& __ec) noexcept { return is_fifo(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(file_status __s) noexcept { return __s.type() == file_type::regular; } +inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) { return is_regular_file(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p, error_code& __ec) noexcept { return is_regular_file(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept { return __s.type() == file_type::symlink; } +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) { return is_symlink(__symlink_status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p, error_code& __ec) noexcept { return is_symlink(__symlink_status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept { return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); } +inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) { return is_other(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p, error_code& __ec) noexcept { return is_other(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept { return __s.type() == file_type::socket; } +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) { return is_socket(__status(__p)); } +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p, error_code& __ec) noexcept { return is_socket(__status(__p, &__ec)); } +inline _LIBCPP_INLINE_VISIBILITY file_time_type last_write_time(const path& __p) { return __last_write_time(__p); } +inline _LIBCPP_INLINE_VISIBILITY file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); } +inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); } +_LIBCPP_FUNC_VIS void __permissions(const path&, perms, perm_options, error_code* = nullptr); +inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); } +inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); } + +inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __base, error_code& __ec) { path __tmp = __weakly_canonical(__p, &__ec); if (__ec) return {}; @@ -463,29 +151,12 @@ inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, return __tmp.lexically_proximate(__tmp_base); } -inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, - error_code& __ec) { - return proximate(__p, current_path(), __ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path -proximate(const path& __p, const path& __base = current_path()) { - return __weakly_canonical(__p).lexically_proximate( - __weakly_canonical(__base)); -} - -inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) { - return __read_symlink(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p, - error_code& __ec) { - return __read_symlink(__p, &__ec); -} +inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, error_code& __ec) { return proximate(__p, current_path(), __ec); } +inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base)); } +inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p) { return __read_symlink(__p); } +inline _LIBCPP_INLINE_VISIBILITY path read_symlink(const path& __p, error_code& __ec) { return __read_symlink(__p, &__ec); } -inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, - const path& __base, - error_code& __ec) { +inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __base, error_code& __ec) { path __tmp = __weakly_canonical(__p, &__ec); if (__ec) return path(); @@ -495,100 +166,27 @@ inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, return __tmp.lexically_relative(__tmpbase); } -inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, - error_code& __ec) { - return relative(__p, current_path(), __ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path -relative(const path& __p, const path& __base = current_path()) { - return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); -} - -inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) { - return __remove_all(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p, - error_code& __ec) { - return __remove_all(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) { - return __remove(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p, - error_code& __ec) noexcept { - return __remove(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, - const path& __to) { - return __rename(__from, __to); -} - -inline _LIBCPP_INLINE_VISIBILITY void -rename(const path& __from, const path& __to, error_code& __ec) noexcept { - return __rename(__from, __to, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, - uintmax_t __ns) { - return __resize_file(__p, __ns); -} - -inline _LIBCPP_INLINE_VISIBILITY void -resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { - return __resize_file(__p, __ns, &__ec); -} - -_LIBCPP_FUNC_VIS -space_info __space(const path&, error_code* __ec = nullptr); - -inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) { - return __space(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p, - error_code& __ec) noexcept { - return __space(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) { - return __status(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p, - error_code& __ec) noexcept { - return __status(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) { - return __symlink_status(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY file_status -symlink_status(const path& __p, error_code& __ec) noexcept { - return __symlink_status(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() { - return __temp_directory_path(); -} - -inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) { - return __temp_directory_path(&__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) { - return __weakly_canonical(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p, - error_code& __ec) { - return __weakly_canonical(__p, &__ec); -} +inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, error_code& __ec) { return relative(__p, current_path(), __ec); } +inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); } +inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) { return __remove_all(__p); } +inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p, error_code& __ec) { return __remove_all(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p) { return __remove(__p); } +inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p, error_code& __ec) noexcept { return __remove(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, const path& __to) { return __rename(__from, __to); } +inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); } +inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); } +_LIBCPP_FUNC_VIS space_info __space(const path&, error_code* __ec = nullptr); +inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) { return __space(__p); } +inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) { return __status(__p); } +inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p, error_code& __ec) noexcept { return __status(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) { return __symlink_status(__p); } +inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p, error_code& __ec) noexcept { return __symlink_status(__p, &__ec); } +inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() { return __temp_directory_path(); } +inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path(error_code& __ec) { return __temp_directory_path(&__ec); } +inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p) { return __weakly_canonical(__p); } +inline _LIBCPP_INLINE_VISIBILITY path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); } _LIBCPP_AVAILABILITY_FILESYSTEM_POP diff --git contrib/llvm-project/libcxx/include/__filesystem/path.h contrib/llvm-project/libcxx/include/__filesystem/path.h index a6d1ee997d91..77547cbacb7d 100644 --- contrib/llvm-project/libcxx/include/__filesystem/path.h +++ contrib/llvm-project/libcxx/include/__filesystem/path.h @@ -12,16 +12,16 @@ #include <__availability> #include <__config> -#include <string> -#include <type_traits> #include <__iterator/back_insert_iterator.h> #include <__iterator/iterator_traits.h> #include <cstddef> +#include <string> #include <string_view> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) -# include <locale> # include <iomanip> // for quoted +# include <locale> #endif #ifndef _LIBCPP_CXX03_LANG diff --git contrib/llvm-project/libcxx/include/__filesystem/path_iterator.h contrib/llvm-project/libcxx/include/__filesystem/path_iterator.h index 62f8dc6fd357..08039e4c8a36 100644 --- contrib/llvm-project/libcxx/include/__filesystem/path_iterator.h +++ contrib/llvm-project/libcxx/include/__filesystem/path_iterator.h @@ -12,9 +12,9 @@ #include <__availability> #include <__config> +#include <__debug> #include <__filesystem/path.h> #include <__iterator/iterator_traits.h> -#include <__debug> #include <cstddef> #include <string> #include <string_view> @@ -38,15 +38,13 @@ public: }; public: - typedef bidirectional_iterator_tag iterator_category; + typedef input_iterator_tag iterator_category; + typedef bidirectional_iterator_tag iterator_concept; typedef path value_type; typedef ptrdiff_t difference_type; typedef const path* pointer; - typedef const path& reference; - - typedef void - __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator + typedef path reference; public: _LIBCPP_INLINE_VISIBILITY diff --git contrib/llvm-project/libcxx/include/__format/format_arg.h contrib/llvm-project/libcxx/include/__format/format_arg.h index 59429c13d415..da829d52fbfe 100644 --- contrib/llvm-project/libcxx/include/__format/format_arg.h +++ contrib/llvm-project/libcxx/include/__format/format_arg.h @@ -14,7 +14,9 @@ #include <__config> #include <__format/format_error.h> #include <__format/format_fwd.h> +#include <__format/format_parse_context.h> #include <__functional_base> +#include <__memory/addressof.h> #include <__variant/monostate.h> #include <string> #include <string_view> @@ -56,7 +58,8 @@ enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t { __long_double, __const_char_type_ptr, __string_view, - __ptr + __ptr, + __handle }; } // namespace __format @@ -104,6 +107,8 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__string_view); case __format::__arg_t::__ptr: return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__ptr); + case __format::__arg_t::__handle: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__handle); } _LIBCPP_UNREACHABLE(); } @@ -111,8 +116,7 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { template <class _Context> class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg { public: - // TODO FMT Define the handle class. - class handle; + class _LIBCPP_TEMPLATE_VIS handle; _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept : __type_{__format::__arg_t::__none} {} @@ -161,7 +165,7 @@ private: const char_type* __const_char_type_ptr; basic_string_view<char_type> __string_view; const void* __ptr; - // TODO FMT Add the handle. + handle __handle; }; __format::__arg_t __type_; @@ -245,7 +249,37 @@ private: explicit basic_format_arg(nullptr_t) noexcept : __ptr(nullptr), __type_(__format::__arg_t::__ptr) {} - // TODO FMT Implement the _Tp* constructor. + template <class _Tp> + requires is_void_v<_Tp> _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(_Tp* __p) noexcept + : __ptr(__p), __type_(__format::__arg_t::__ptr) {} + + template <class _Tp> + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(const _Tp& __v) noexcept + : __handle(__v), __type_(__format::__arg_t::__handle) {} +}; + +template <class _Context> +class _LIBCPP_TEMPLATE_VIS basic_format_arg<_Context>::handle { + friend class basic_format_arg<_Context>; + +public: + _LIBCPP_HIDE_FROM_ABI + void format(basic_format_parse_context<char_type>& __parse_ctx, _Context& __ctx) const { + __format_(__parse_ctx, __ctx, __ptr_); + } + +private: + const void* __ptr_; + void (*__format_)(basic_format_parse_context<char_type>&, _Context&, const void*); + + template <class _Tp> + _LIBCPP_HIDE_FROM_ABI explicit handle(const _Tp& __v) noexcept + : __ptr_(_VSTD::addressof(__v)), + __format_([](basic_format_parse_context<char_type>& __parse_ctx, _Context& __ctx, const void* __ptr) { + typename _Context::template formatter_type<_Tp> __f; + __parse_ctx.advance_to(__f.parse(__parse_ctx)); + __ctx.advance_to(__f.format(*static_cast<const _Tp*>(__ptr), __ctx)); + }) {} }; #endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) diff --git contrib/llvm-project/libcxx/include/__format/formatter.h contrib/llvm-project/libcxx/include/__format/formatter.h index 1adce75a8611..38b73bba32f3 100644 --- contrib/llvm-project/libcxx/include/__format/formatter.h +++ contrib/llvm-project/libcxx/include/__format/formatter.h @@ -38,26 +38,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD // to support compilers with partial C++20 support. #if !defined(_LIBCPP_HAS_NO_CONCEPTS) -// Currently not implemented specializations throw an exception when used. This -// does not conform to the Standard. However not all Standard defined formatters -// have been implemented yet. Until that time the current behavior is intended. -// TODO FMT Disable the default template. +/// The default formatter template. +/// +/// [format.formatter.spec]/5 +/// If F is a disabled specialization of formatter, these values are false: +/// - is_default_constructible_v<F>, +/// - is_copy_constructible_v<F>, +/// - is_move_constructible_v<F>, +/// - is_copy_assignable<F>, and +/// - is_move_assignable<F>. template <class _Tp, class _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter { - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI auto parse(auto& __parse_ctx) - -> decltype(__parse_ctx.begin()) { - __throw(); - } - - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI auto format(_Tp, auto& __ctx) - -> decltype(__ctx.out()) { - __throw(); - } - -private: - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw() { - __throw_format_error("Argument type not implemented yet"); - } + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; }; namespace __format_spec { @@ -190,6 +184,34 @@ __write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first, return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill); } +/** + * @overload + * + * Writes additional zero's for the precision before the exponent. + * This is used when the precision requested in the format string is larger + * than the maximum precision of the floating-point type. These precision + * digits are always 0. + * + * @param __exponent The location of the exponent character. + * @param __num_trailing_zeros The number of 0's to write before the exponent + * character. + */ +template <class _CharT, class _Fill> +_LIBCPP_HIDE_FROM_ABI auto __write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first, + const _CharT* __last, size_t __size, size_t __width, _Fill __fill, + __format_spec::_Flags::_Alignment __alignment, const _CharT* __exponent, + size_t __num_trailing_zeros) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used"); + + __padding_size_result __padding = __padding_size(__size + __num_trailing_zeros, __width, __alignment); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill); + __out_it = _VSTD::copy(__first, __exponent, _VSTD::move(__out_it)); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0')); + __out_it = _VSTD::copy(__exponent, __last, _VSTD::move(__out_it)); + return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill); +} + /** * @overload * diff --git contrib/llvm-project/libcxx/include/__format/formatter_bool.h contrib/llvm-project/libcxx/include/__format/formatter_bool.h index fdd1d75355d2..1e40bc0a435a 100644 --- contrib/llvm-project/libcxx/include/__format/formatter_bool.h +++ contrib/llvm-project/libcxx/include/__format/formatter_bool.h @@ -102,7 +102,7 @@ using __formatter_bool = __formatter_integral<__parser_bool<_CharT>>; // For each charT, for each cv-unqualified arithmetic type ArithmeticT other // than char, wchar_t, char8_t, char16_t, or char32_t, a specialization -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<bool, _CharT> : public __format_spec::__formatter_bool<_CharT> { using _Base = __format_spec::__formatter_bool<_CharT>; diff --git contrib/llvm-project/libcxx/include/__format/formatter_floating_point.h contrib/llvm-project/libcxx/include/__format/formatter_floating_point.h new file mode 100644 index 000000000000..2e710b409deb --- /dev/null +++ contrib/llvm-project/libcxx/include/__format/formatter_floating_point.h @@ -0,0 +1,717 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H +#define _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H + +#include <__algorithm/copy.h> +#include <__algorithm/copy_n.h> +#include <__algorithm/fill_n.h> +#include <__algorithm/find.h> +#include <__algorithm/min.h> +#include <__algorithm/rotate.h> +#include <__algorithm/transform.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include <__debug> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/format_string.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/parser_std_format_spec.h> +#include <__utility/move.h> +#include <charconv> +#include <cmath> + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# include <locale> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// TODO FMT Remove this once we require compilers with proper C++20 support. +// If the compiler has no concepts support, the format header will be disabled. +// Without concepts support enable_if needs to be used and that too much effort +// to support compilers with partial C++20 support. +# if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +namespace __format_spec { + +template <floating_point _Tp> +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +template <floating_point _Tp> +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +template <floating_point _Tp> +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt, int __precision) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt, __precision); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +// https://en.cppreference.com/w/cpp/language/types#cite_note-1 +// float min subnormal: +/-0x1p-149 max: +/- 3.402,823,4 10^38 +// double min subnormal: +/-0x1p-1074 max +/- 1.797,693,134,862,315,7 10^308 +// long double (x86) min subnormal: +/-0x1p-16446 max: +/- 1.189,731,495,357,231,765,021 10^4932 +// +// The maximum number of digits required for the integral part is based on the +// maximum's value power of 10. Every power of 10 requires one additional +// decimal digit. +// The maximum number of digits required for the fractional part is based on +// the minimal subnormal hexadecimal output's power of 10. Every division of a +// fraction's binary 1 by 2, requires one additional decimal digit. +// +// The maximum size of a formatted value depends on the selected output format. +// Ignoring the fact the format string can request a precision larger than the +// values maximum required, these values are: +// +// sign 1 code unit +// __max_integral +// radix point 1 code unit +// __max_fractional +// exponent character 1 code unit +// sign 1 code unit +// __max_fractional_value +// ----------------------------------- +// total 4 code units extra required. +// +// TODO FMT Optimize the storage to avoid storing digits that are known to be zero. +// https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/ + +// TODO FMT Add long double specialization when to_chars has proper long double support. +template <class _Tp> +struct __traits; + +template <floating_point _Fp> +static constexpr size_t __float_buffer_size(int __precision) { + using _Traits = __traits<_Fp>; + return 4 + _Traits::__max_integral + __precision + _Traits::__max_fractional_value; +} + +template <> +struct __traits<float> { + static constexpr int __max_integral = 38; + static constexpr int __max_fractional = 149; + static constexpr int __max_fractional_value = 3; + static constexpr size_t __stack_buffer_size = 256; + + static constexpr int __hex_precision_digits = 3; +}; + +template <> +struct __traits<double> { + static constexpr int __max_integral = 308; + static constexpr int __max_fractional = 1074; + static constexpr int __max_fractional_value = 4; + static constexpr size_t __stack_buffer_size = 1024; + + static constexpr int __hex_precision_digits = 4; +}; + +/// Helper class to store the conversion buffer. +/// +/// Depending on the maxium size required for a value, the buffer is allocated +/// on the stack or the heap. +template <floating_point _Fp> +class _LIBCPP_TEMPLATE_VIS __float_buffer { + using _Traits = __traits<_Fp>; + +public: + // TODO FMT Improve this constructor to do a better estimate. + // When using a scientific formatting with a precision of 6 a stack buffer + // will always suffice. At the moment that isn't important since floats and + // doubles use a stack buffer, unless the precision used in the format string + // is large. + // When supporting long doubles the __max_integral part becomes 4932 which + // may be too much for some platforms. For these cases a better estimate is + // required. + explicit _LIBCPP_HIDE_FROM_ABI __float_buffer(int __precision) + : __precision_(__precision != -1 ? __precision : _Traits::__max_fractional) { + + // When the precision is larger than _Traits::__max_fractional the digits in + // the range (_Traits::__max_fractional, precision] will contain the value + // zero. There's no need to request to_chars to write these zeros: + // - When the value is large a temporary heap buffer needs to be allocated. + // - When to_chars writes the values they need to be "copied" to the output: + // - char: std::fill on the output iterator is faster than std::copy. + // - wchar_t: same argument as char, but additional std::copy won't work. + // The input is always a char buffer, so every char in the buffer needs + // to be converted from a char to a wchar_t. + if (__precision_ > _Traits::__max_fractional) { + __num_trailing_zeros_ = __precision_ - _Traits::__max_fractional; + __precision_ = _Traits::__max_fractional; + } + + __size_ = __format_spec::__float_buffer_size<_Fp>(__precision_); + if (__size_ > _Traits::__stack_buffer_size) + // The allocated buffer's contents don't need initialization. + __begin_ = allocator<char>{}.allocate(__size_); + else + __begin_ = __buffer_; + } + + _LIBCPP_HIDE_FROM_ABI ~__float_buffer() { + if (__size_ > _Traits::__stack_buffer_size) + allocator<char>{}.deallocate(__begin_, __size_); + } + _LIBCPP_HIDE_FROM_ABI __float_buffer(const __float_buffer&) = delete; + _LIBCPP_HIDE_FROM_ABI __float_buffer& operator=(const __float_buffer&) = delete; + + _LIBCPP_HIDE_FROM_ABI char* begin() const { return __begin_; } + _LIBCPP_HIDE_FROM_ABI char* end() const { return __begin_ + __size_; } + + _LIBCPP_HIDE_FROM_ABI int __precision() const { return __precision_; } + _LIBCPP_HIDE_FROM_ABI int __num_trailing_zeros() const { return __num_trailing_zeros_; } + _LIBCPP_HIDE_FROM_ABI void __remove_trailing_zeros() { __num_trailing_zeros_ = 0; } + +private: + int __precision_; + int __num_trailing_zeros_{0}; + size_t __size_; + char* __begin_; + char __buffer_[_Traits::__stack_buffer_size]; +}; + +struct __float_result { + /// Points at the beginning of the integral part in the buffer. + /// + /// When there's no sign character this points at the start of the buffer. + char* __integral; + + /// Points at the radix point, when not present it's the same as \ref __last. + char* __radix_point; + + /// Points at the exponent character, when not present it's the same as \ref __last. + char* __exponent; + + /// Points beyond the last written element in the buffer. + char* __last; +}; + +/// Finds the position of the exponent character 'e' at the end of the buffer. +/// +/// Assuming there is an exponent the input will terminate with +/// eSdd and eSdddd (S = sign, d = digit) +/// +/// \returns a pointer to the exponent or __last when not found. +constexpr inline _LIBCPP_HIDE_FROM_ABI char* __find_exponent(char* __first, char* __last) { + ptrdiff_t __size = __last - __first; + if (__size > 4) { + __first = __last - _VSTD::min(__size, ptrdiff_t(6)); + for (; __first != __last - 3; ++__first) { + if (*__first == 'e') + return __first; + } + } + return __last; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffer<_Fp>& __buffer, _Tp __value, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value); + + __result.__exponent = __format_spec::__find_exponent(__result.__integral, __result.__last); + + // Constrains: + // - There's at least one decimal digit before the radix point. + // - The radix point, when present, is placed before the exponent. + __result.__radix_point = _VSTD::find(__result.__integral + 1, __result.__exponent, '.'); + + // When the radix point isn't found its position is the exponent instead of + // __result.__last. + if (__result.__radix_point == __result.__exponent) + __result.__radix_point = __result.__last; + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + if (__precision == -1) + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex); + else + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex, __precision); + + // H = one or more hex-digits + // S = sign + // D = one or more decimal-digits + // When the fractional part is zero and no precision the output is 0p+0 + // else the output is 0.HpSD + // So testing the second position can differentiate between these two cases. + char* __first = __integral + 1; + if (*__first == '.') { + __result.__radix_point = __first; + // One digit is the minimum + // 0.hpSd + // ^-- last + // ^---- integral = end of search + // ^-------- start of search + // 0123456 + // + // Four digits is the maximum + // 0.hpSdddd + // ^-- last + // ^---- integral = end of search + // ^-------- start of search + // 0123456789 + static_assert(__traits<_Fp>::__hex_precision_digits <= 4, "Guard against possible underflow."); + + char* __last = __result.__last - 2; + __first = __last - __traits<_Fp>::__hex_precision_digits; + __result.__exponent = _VSTD::find(__first, __last, 'p'); + } else { + __result.__radix_point = __result.__last; + __result.__exponent = __first; + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'p'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result = + __format_spec::__format_buffer_hexadecimal_lower_case(__buffer, __value, __precision, __integral); + _VSTD::transform(__result.__integral, __result.__exponent, __result.__integral, __hex_to_upper); + *__result.__exponent = 'P'; + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = + __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision); + + char* __first = __integral + 1; + _LIBCPP_ASSERT(__first != __result.__last, "No exponent present"); + if (*__first == '.') { + __result.__radix_point = __first; + __result.__exponent = __format_spec::__find_exponent(__first + 1, __result.__last); + } else { + __result.__radix_point = __result.__last; + __result.__exponent = __first; + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result = + __format_spec::__format_buffer_scientific_lower_case(__buffer, __value, __precision, __integral); + *__result.__exponent = 'E'; + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::fixed, __precision); + + // When there's no precision there's no radix point. + // Else the radix point is placed at __precision + 1 from the end. + // By converting __precision to a bool the subtraction can be done + // unconditionally. + __result.__radix_point = __result.__last - (__precision + bool(__precision)); + __result.__exponent = __result.__last; + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last), + "Post-condition failure."); + // clang-format on + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + + __buffer.__remove_trailing_zeros(); + + __float_result __result; + __result.__integral = __integral; + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::general, __precision); + + char* __first = __integral + 1; + if (__first == __result.__last) { + __result.__radix_point = __result.__last; + __result.__exponent = __result.__last; + } else { + __result.__exponent = __format_spec::__find_exponent(__first, __result.__last); + if (__result.__exponent != __result.__last) + // In scientific mode if there's a radix point it will always be after + // the first digit. (This is the position __first points at). + __result.__radix_point = *__first == '.' ? __first : __result.__last; + else { + // In fixed mode the algorithm truncates trailing spaces and possibly the + // radix point. There's no good guess for the position of the radix point + // therefore scan the output after the first digit. + __result.__radix_point = _VSTD::find(__first, __result.__last, '.'); + } + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template <class _Fp, class _Tp> +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_upper_case(__float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + __float_result __result = + __format_spec::__format_buffer_general_lower_case(__buffer, __value, __precision, __integral); + if (__result.__exponent != __result.__last) + *__result.__exponent = 'E'; + return __result; +} + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION +template <class _OutIt, class _Fp, class _CharT> +_LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(_OutIt __out_it, const __float_buffer<_Fp>& __buffer, + const __float_result& __result, _VSTD::locale __loc, + size_t __width, _Flags::_Alignment __alignment, + _CharT __fill) { + const auto& __np = use_facet<numpunct<_CharT>>(__loc); + string __grouping = __np.grouping(); + char* __first = __result.__integral; + // When no radix point or exponent are present __last will be __result.__last. + char* __last = _VSTD::min(__result.__radix_point, __result.__exponent); + + ptrdiff_t __digits = __last - __first; + if (!__grouping.empty()) { + if (__digits <= __grouping[0]) + __grouping.clear(); + else + __grouping = __determine_grouping(__digits, __grouping); + } + + size_t __size = __result.__last - __buffer.begin() + // Formatted string + __buffer.__num_trailing_zeros() + // Not yet rendered zeros + __grouping.size() - // Grouping contains one + !__grouping.empty(); // additional character + + __formatter::__padding_size_result __padding = {0, 0}; + bool __zero_padding = __alignment == _Flags::_Alignment::__default; + if (__size < __width) { + if (__zero_padding) { + __alignment = _Flags::_Alignment::__right; + __fill = _CharT('0'); + } + + __padding = __formatter::__padding_size(__size, __width, __alignment); + } + + // sign and (zero padding or alignment) + if (__zero_padding && __first != __buffer.begin()) + *__out_it++ = *__buffer.begin(); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill); + if (!__zero_padding && __first != __buffer.begin()) + *__out_it++ = *__buffer.begin(); + + // integral part + if (__grouping.empty()) { + __out_it = _VSTD::copy_n(__first, __digits, _VSTD::move(__out_it)); + } else { + auto __r = __grouping.rbegin(); + auto __e = __grouping.rend() - 1; + _CharT __sep = __np.thousands_sep(); + // The output is divided in small groups of numbers to write: + // - A group before the first separator. + // - A separator and a group, repeated for the number of separators. + // - A group after the last separator. + // This loop achieves that process by testing the termination condition + // midway in the loop. + while (true) { + __out_it = _VSTD::copy_n(__first, *__r, _VSTD::move(__out_it)); + __first += *__r; + + if (__r == __e) + break; + + ++__r; + *__out_it++ = __sep; + } + } + + // fractional part + if (__result.__radix_point != __result.__last) { + *__out_it++ = __np.decimal_point(); + __out_it = _VSTD::copy(__result.__radix_point + 1, __result.__exponent, _VSTD::move(__out_it)); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __buffer.__num_trailing_zeros(), _CharT('0')); + } + + // exponent + if (__result.__exponent != __result.__last) + __out_it = _VSTD::copy(__result.__exponent, __result.__last, _VSTD::move(__out_it)); + + // alignment + return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill); +} + +# endif // _LIBCPP_HAS_NO_LOCALIZATION + +template <__formatter::__char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __formatter_floating_point : public __parser_floating_point<_CharT> { +public: + template <floating_point _Tp> + _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) -> decltype(__ctx.out()) { + if (this->__width_needs_substitution()) + this->__substitute_width_arg_id(__ctx.arg(this->__width)); + + bool __negative = _VSTD::signbit(__value); + + if (!_VSTD::isfinite(__value)) [[unlikely]] + return __format_non_finite(__ctx.out(), __negative, _VSTD::isnan(__value)); + + bool __has_precision = this->__has_precision_field(); + if (this->__precision_needs_substitution()) + this->__substitute_precision_arg_id(__ctx.arg(this->__precision)); + + // Depending on the std-format-spec string the sign and the value + // might not be outputted together: + // - zero-padding may insert additional '0' characters. + // Therefore the value is processed as a non negative value. + // The function @ref __insert_sign will insert a '-' when the value was + // negative. + + if (__negative) + __value = _VSTD::copysign(__value, +1.0); + + // TODO FMT _Fp should just be _Tp when to_chars has proper long double support. + using _Fp = conditional_t<same_as<_Tp, long double>, double, _Tp>; + // Force the type of the precision to avoid -1 to become an unsigned value. + __float_buffer<_Fp> __buffer(__has_precision ? int(this->__precision) : -1); + __float_result __result = __format_buffer(__buffer, __value, __negative, __has_precision); + + if (this->__alternate_form && __result.__radix_point == __result.__last) { + *__result.__last++ = '.'; + + // When there is an exponent the point needs to be moved before the + // exponent. When there's no exponent the rotate does nothing. Since + // rotate tests whether the operation is a nop, call it unconditionally. + _VSTD::rotate(__result.__exponent, __result.__last - 1, __result.__last); + __result.__radix_point = __result.__exponent; + + // The radix point is always placed before the exponent. + // - No exponent needs to point to the new last. + // - An exponent needs to move one position to the right. + // So it's safe to increment the value unconditionally. + ++__result.__exponent; + } + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + if (this->__locale_specific_form) + return __format_spec::__format_locale_specific_form(__ctx.out(), __buffer, __result, __ctx.locale(), + this->__width, this->__alignment, this->__fill); +# endif + + ptrdiff_t __size = __result.__last - __buffer.begin(); + int __num_trailing_zeros = __buffer.__num_trailing_zeros(); + if (__size + __num_trailing_zeros >= this->__width) { + if (__num_trailing_zeros && __result.__exponent != __result.__last) + // Insert trailing zeros before exponent character. + return _VSTD::copy(__result.__exponent, __result.__last, + _VSTD::fill_n(_VSTD::copy(__buffer.begin(), __result.__exponent, __ctx.out()), + __num_trailing_zeros, _CharT('0'))); + + return _VSTD::fill_n(_VSTD::copy(__buffer.begin(), __result.__last, __ctx.out()), __num_trailing_zeros, + _CharT('0')); + } + + auto __out_it = __ctx.out(); + char* __first = __buffer.begin(); + if (this->__alignment == _Flags::_Alignment::__default) { + // When there is a sign output it before the padding. Note the __size + // doesn't need any adjustment, regardless whether the sign is written + // here or in __formatter::__write. + if (__first != __result.__integral) + *__out_it++ = *__first++; + // After the sign is written, zero padding is the same a right alignment + // with '0'. + this->__alignment = _Flags::_Alignment::__right; + this->__fill = _CharT('0'); + } + + if (__num_trailing_zeros) + return __formatter::__write(_VSTD::move(__out_it), __first, __result.__last, __size, this->__width, this->__fill, + this->__alignment, __result.__exponent, __num_trailing_zeros); + + return __formatter::__write(_VSTD::move(__out_it), __first, __result.__last, __size, this->__width, this->__fill, + this->__alignment); + } + +private: + template <class _OutIt> + _LIBCPP_HIDE_FROM_ABI _OutIt __format_non_finite(_OutIt __out_it, bool __negative, bool __isnan) { + char __buffer[4]; + char* __last = __insert_sign(__buffer, __negative, this->__sign); + + // to_char can return inf, infinity, nan, and nan(n-char-sequence). + // The format library requires inf and nan. + // All in one expression to avoid dangling references. + __last = _VSTD::copy_n(&("infnanINFNAN"[6 * (this->__type == _Flags::_Type::__float_hexadecimal_upper_case || + this->__type == _Flags::_Type::__scientific_upper_case || + this->__type == _Flags::_Type::__fixed_upper_case || + this->__type == _Flags::_Type::__general_upper_case) + + 3 * __isnan]), + 3, __last); + + // [format.string.std]/13 + // A zero (0) character preceding the width field pads the field with + // leading zeros (following any indication of sign or base) to the field + // width, except when applied to an infinity or NaN. + if (this->__alignment == _Flags::_Alignment::__default) + this->__alignment = _Flags::_Alignment::__right; + + ptrdiff_t __size = __last - __buffer; + if (__size >= this->__width) + return _VSTD::copy_n(__buffer, __size, _VSTD::move(__out_it)); + + return __formatter::__write(_VSTD::move(__out_it), __buffer, __last, __size, this->__width, this->__fill, + this->__alignment); + } + + /// Fills the buffer with the data based on the requested formatting. + /// + /// This function, when needed, turns the characters to upper case and + /// determines the "interesting" locations which are returned to the caller. + /// + /// This means the caller never has to convert the contents of the buffer to + /// upper case or search for radix points and the location of the exponent. + /// This gives a bit of overhead. The original code didn't do that, but due + /// to the number of possible additional work needed to turn this number to + /// the proper output the code was littered with tests for upper cases and + /// searches for radix points and exponents. + /// - When a precision larger than the type's precision is selected + /// additional zero characters need to be written before the exponent. + /// - alternate form needs to add a radix point when not present. + /// - localization needs to do grouping in the integral part. + template <class _Fp, class _Tp> + // TODO FMT _Fp should just be _Tp when to_chars has proper long double support. + _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer(__float_buffer<_Fp>& __buffer, _Tp __value, bool __negative, + bool __has_precision) { + char* __first = __insert_sign(__buffer.begin(), __negative, this->__sign); + switch (this->__type) { + case _Flags::_Type::__default: + return __format_spec::__format_buffer_default(__buffer, __value, __first); + + case _Flags::_Type::__float_hexadecimal_lower_case: + return __format_spec::__format_buffer_hexadecimal_lower_case( + __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first); + + case _Flags::_Type::__float_hexadecimal_upper_case: + return __format_spec::__format_buffer_hexadecimal_upper_case( + __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first); + + case _Flags::_Type::__scientific_lower_case: + return __format_spec::__format_buffer_scientific_lower_case(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__scientific_upper_case: + return __format_spec::__format_buffer_scientific_upper_case(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__fixed_lower_case: + case _Flags::_Type::__fixed_upper_case: + return __format_spec::__format_buffer_fixed(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__general_lower_case: + return __format_spec::__format_buffer_general_lower_case(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__general_upper_case: + return __format_spec::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first); + + default: + _LIBCPP_ASSERT(false, "The parser should have validated the type"); + _LIBCPP_UNREACHABLE(); + } + } +}; + +} //namespace __format_spec + +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<float, _CharT> + : public __format_spec::__formatter_floating_point<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<double, _CharT> + : public __format_spec::__formatter_floating_point<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long double, _CharT> + : public __format_spec::__formatter_floating_point<_CharT> {}; + +# endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H diff --git contrib/llvm-project/libcxx/include/__format/formatter_integer.h contrib/llvm-project/libcxx/include/__format/formatter_integer.h index 767df36e61eb..e1f3d4e34897 100644 --- contrib/llvm-project/libcxx/include/__format/formatter_integer.h +++ contrib/llvm-project/libcxx/include/__format/formatter_integer.h @@ -81,25 +81,25 @@ using __formatter_integer = __formatter_integral<__parser_integer<_CharT>>; // than char, wchar_t, char8_t, char16_t, or char32_t, a specialization // Signed integral types. -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<signed char, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<short, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<int, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long long, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; #ifndef _LIBCPP_HAS_NO_INT128 -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT> : public __format_spec::__formatter_integer<_CharT> { @@ -119,28 +119,28 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT #endif // Unsigned integral types. -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned char, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned short, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long long, _CharT> : public __format_spec::__formatter_integer<_CharT> {}; #ifndef _LIBCPP_HAS_NO_INT128 -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT> : public __format_spec::__formatter_integer<_CharT> { diff --git contrib/llvm-project/libcxx/include/__format/formatter_integral.h contrib/llvm-project/libcxx/include/__format/formatter_integral.h index 5f1353effd77..f164ee610974 100644 --- contrib/llvm-project/libcxx/include/__format/formatter_integral.h +++ contrib/llvm-project/libcxx/include/__format/formatter_integral.h @@ -10,15 +10,15 @@ #ifndef _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H #define _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H +#include <__algorithm/copy.h> +#include <__algorithm/copy_n.h> +#include <__algorithm/fill_n.h> +#include <__algorithm/transform.h> #include <__config> #include <__format/format_error.h> #include <__format/format_fwd.h> #include <__format/formatter.h> #include <__format/parser_std_format_spec.h> -#include <__algorithm/copy.h> -#include <__algorithm/copy_n.h> -#include <__algorithm/fill_n.h> -#include <__algorithm/transform.h> #include <array> #include <charconv> #include <concepts> @@ -82,7 +82,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace __format_spec { /** Wrapper around @ref to_chars, returning the output pointer. */ -template <class _Tp> +template <integral _Tp> _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, int __base) { // TODO FMT Evaluate code overhead due to not calling the internal function diff --git contrib/llvm-project/libcxx/include/__format/formatter_pointer.h contrib/llvm-project/libcxx/include/__format/formatter_pointer.h new file mode 100644 index 000000000000..aa2eb641c6c6 --- /dev/null +++ contrib/llvm-project/libcxx/include/__format/formatter_pointer.h @@ -0,0 +1,91 @@ +// -*- 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 _LIBCPP___FORMAT_FORMATTER_POINTER_H +#define _LIBCPP___FORMAT_FORMATTER_POINTER_H + +#include <__algorithm/copy.h> +#include <__availability> +#include <__config> +#include <__debug> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/parser_std_format_spec.h> +#include <__iterator/access.h> +#include <__nullptr> +#include <cstdint> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// TODO FMT Remove this once we require compilers with proper C++20 support. +// If the compiler has no concepts support, the format header will be disabled. +// Without concepts support enable_if needs to be used and that too much effort +// to support compilers with partial C++20 support. +# if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +namespace __format_spec { + +template <__formatter::__char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __formatter_pointer : public __parser_pointer<_CharT> { +public: + _LIBCPP_HIDE_FROM_ABI auto format(const void* __ptr, auto& __ctx) -> decltype(__ctx.out()) { + _LIBCPP_ASSERT(this->__alignment != _Flags::_Alignment::__default, + "The call to parse should have updated the alignment"); + if (this->__width_needs_substitution()) + this->__substitute_width_arg_id(__ctx.arg(this->__width)); + + // This code looks a lot like the code to format a hexadecimal integral, + // but that code isn't public. Making that code public requires some + // refactoring. + // TODO FMT Remove code duplication. + char __buffer[2 + 2 * sizeof(uintptr_t)]; + __buffer[0] = '0'; + __buffer[1] = 'x'; + char* __last = __to_buffer(__buffer + 2, _VSTD::end(__buffer), reinterpret_cast<uintptr_t>(__ptr), 16); + + unsigned __size = __last - __buffer; + if (__size >= this->__width) + return _VSTD::copy(__buffer, __last, __ctx.out()); + + return __formatter::__write(__ctx.out(), __buffer, __last, __size, this->__width, this->__fill, this->__alignment); + } +}; + +} // namespace __format_spec + +// [format.formatter.spec]/2.4 +// For each charT, the pointer type specializations template<> +// - struct formatter<nullptr_t, charT>; +// - template<> struct formatter<void*, charT>; +// - template<> struct formatter<const void*, charT>; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<nullptr_t, _CharT> + : public __format_spec::__formatter_pointer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<void*, _CharT> + : public __format_spec::__formatter_pointer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const void*, _CharT> + : public __format_spec::__formatter_pointer<_CharT> {}; + +# endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_POINTER_H diff --git contrib/llvm-project/libcxx/include/__format/formatter_string.h contrib/llvm-project/libcxx/include/__format/formatter_string.h index 75a81f5184a0..04950faa4a21 100644 --- contrib/llvm-project/libcxx/include/__format/formatter_string.h +++ contrib/llvm-project/libcxx/include/__format/formatter_string.h @@ -64,7 +64,7 @@ public: // [format.formatter.spec]/2.2 For each charT, the string type specializations // Formatter const char*. -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*, _CharT> : public __format_spec::__formatter_string<_CharT> { @@ -98,7 +98,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT }; // Formatter char*. -template <class _CharT> +template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT*, _CharT> : public formatter<const _CharT*, _CharT> { using _Base = formatter<const _CharT*, _CharT>; @@ -110,7 +110,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT }; // Formatter const char[]. -template <class _CharT, size_t _Size> +template <__formatter::__char_type _CharT, size_t _Size> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT[_Size], _CharT> : public __format_spec::__formatter_string<_CharT> { @@ -123,7 +123,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT }; // Formatter std::string. -template <class _CharT, class _Traits, class _Allocator> +template <__formatter::__char_type _CharT, class _Traits, class _Allocator> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT> : public __format_spec::__formatter_string<_CharT> { @@ -138,7 +138,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT }; // Formatter std::string_view. -template <class _CharT, class _Traits> +template <__formatter::__char_type _CharT, class _Traits> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string_view<_CharT, _Traits>, _CharT> : public __format_spec::__formatter_string<_CharT> { using _Base = __format_spec::__formatter_string<_CharT>; diff --git contrib/llvm-project/libcxx/include/__format/parser_std_format_spec.h contrib/llvm-project/libcxx/include/__format/parser_std_format_spec.h index 9b713b811484..9d893e9ced27 100644 --- contrib/llvm-project/libcxx/include/__format/parser_std_format_spec.h +++ contrib/llvm-project/libcxx/include/__format/parser_std_format_spec.h @@ -214,7 +214,7 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { __format::__parse_arg_id(__begin, __end, __parse_ctx); if (__r.__ptr == __end || *__r.__ptr != _CharT('}')) - __throw_format_error("A format-spec arg-id should terminate at a '}'"); + __throw_format_error("Invalid arg-id"); ++__r.__ptr; return __r; @@ -363,17 +363,6 @@ protected: if (__begin == __end) __throw_format_error("End of input while parsing format-spec precision"); - if (*__begin == _CharT('0')) { - ++__begin; - if (__begin != __end && *__begin >= '0' && *__begin <= '9') - __throw_format_error( - "A format-spec precision field shouldn't have a leading zero"); - - __precision = 0; - __precision_as_arg = 0; - return __begin; - } - if (*__begin == _CharT('{')) { __format::__parse_number_result __arg_id = __parse_arg_id(++__begin, __end, __parse_ctx); @@ -486,6 +475,21 @@ __parse_type(const _CharT* __begin, _Flags& __flags) { return ++__begin; } +/** + * Process the parsed alignment and zero-padding state of arithmetic types. + * + * [format.string.std]/13 + * If the 0 character and an align option both appear, the 0 character is + * ignored. + * + * For the formatter a @ref __default alignment means zero-padding. + */ +_LIBCPP_HIDE_FROM_ABI constexpr void __process_arithmetic_alignment(_Flags& __flags) { + __flags.__zero_padding &= __flags.__alignment == _Flags::_Alignment::__default; + if (!__flags.__zero_padding && __flags.__alignment == _Flags::_Alignment::__default) + __flags.__alignment = _Flags::_Alignment::__right; +} + /** * The parser for the std-format-spec. * @@ -659,23 +663,9 @@ protected: return __begin; } - /** - * Handles the post-parsing updates for the integer types. - * - * Updates the zero-padding and alignment for integer types. - * - * [format.string.std]/13 - * If the 0 character and an align option both appear, the 0 character is - * ignored. - * - * For the formatter a @ref __default alignment means zero-padding. Update - * the alignment based on parsed format string. - */ + /** Handles the post-parsing updates for the integer types. */ _LIBCPP_HIDE_FROM_ABI constexpr void __handle_integer() noexcept { - this->__zero_padding &= this->__alignment == _Flags::_Alignment::__default; - if (!this->__zero_padding && - this->__alignment == _Flags::_Alignment::__default) - this->__alignment = _Flags::_Alignment::__right; + __process_arithmetic_alignment(static_cast<_Flags&>(*this)); } /** @@ -712,8 +702,232 @@ protected: } }; -// TODO FMT Add a parser for floating-point values. -// TODO FMT Add a parser for pointer values. +/** + * The parser for the std-format-spec. + * + * This implements the parser for the floating-point types. + * + * See @ref __parser_string. + */ +template <class _CharT> +class _LIBCPP_TEMPLATE_VIS __parser_floating_point + : public __parser_width, // provides __width(|as_arg) + public __parser_precision, // provides __precision(|as_arg) + public __parser_fill_align<_CharT>, // provides __fill and uses __flags + public _Flags // provides __flags +{ +public: + using char_type = _CharT; + + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + auto __it = __parse(__parse_ctx); + __process_arithmetic_alignment(static_cast<_Flags&>(*this)); + __process_display_type(); + return __it; + } +protected: + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + auto __begin = __parse_ctx.begin(); + auto __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, + static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_sign(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_alternate_form(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_zero_padding(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parser_width::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = __parser_precision::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = + __parse_locale_specific_form(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_type(__begin, static_cast<_Flags&>(*this)); + + if (__begin != __end && *__begin != _CharT('}')) + __throw_format_error( + "The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + /** Processes the parsed std-format-spec based on the parsed display type. */ + _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() { + switch (this->__type) { + case _Flags::_Type::__default: + // When no precision specified then it keeps default since that + // formatting differs from the other types. + if (this->__has_precision_field()) + this->__type = _Flags::_Type::__general_lower_case; + break; + case _Flags::_Type::__float_hexadecimal_lower_case: + case _Flags::_Type::__float_hexadecimal_upper_case: + // Precision specific behavior will be handled later. + break; + case _Flags::_Type::__scientific_lower_case: + case _Flags::_Type::__scientific_upper_case: + case _Flags::_Type::__fixed_lower_case: + case _Flags::_Type::__fixed_upper_case: + case _Flags::_Type::__general_lower_case: + case _Flags::_Type::__general_upper_case: + if (!this->__has_precision_field()) { + // Set the default precision for the call to to_chars. + this->__precision = 6; + this->__precision_as_arg = false; + } + break; + + default: + __throw_format_error("The format-spec type has a type not supported for " + "a floating-point argument"); + } + } +}; + +/** + * The parser for the std-format-spec. + * + * This implements the parser for the pointer types. + * + * See @ref __parser_string. + */ +template <class _CharT> +class _LIBCPP_TEMPLATE_VIS __parser_pointer : public __parser_width, // provides __width(|as_arg) + public __parser_fill_align<_CharT>, // provides __fill and uses __flags + public _Flags // provides __flags +{ +public: + using char_type = _CharT; + + _LIBCPP_HIDE_FROM_ABI constexpr __parser_pointer() { + // Implements LWG3612 Inconsistent pointer alignment in std::format. + // The issue's current status is "Tentatively Ready" and libc++ status is + // still experimental. + // + // TODO FMT Validate this with the final resolution of LWG3612. + this->__alignment = _Flags::_Alignment::__right; + } + + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __it = __parse(__parse_ctx); + __process_display_type(); + return __it; + } + +protected: + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __begin = __parse_ctx.begin(); + auto __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + // An integer presentation type isn't defined in the Standard. + // Since a pointer is formatted as an integer it can be argued it's an + // integer presentation type. However there are two LWG-issues asserting it + // isn't an integer presentation type: + // - LWG3612 Inconsistent pointer alignment in std::format + // - LWG3644 std::format does not define "integer presentation type" + // + // There's a paper to make additional clarifications on the status of + // formatting pointers and proposes additional fields to be valid. That + // paper hasn't been reviewed by the Committee yet. + // - P2510 Formatting pointers + // + // The current implementation assumes formatting pointers isn't covered by + // "integer presentation type". + // TODO FMT Apply the LWG-issues/papers after approval/rejection by the Committee. + + __begin = __parser_width::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = __parse_type(__begin, static_cast<_Flags&>(*this)); + + if (__begin != __end && *__begin != _CharT('}')) + __throw_format_error("The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + /** Processes the parsed std-format-spec based on the parsed display type. */ + _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() { + switch (this->__type) { + case _Flags::_Type::__default: + this->__type = _Flags::_Type::__pointer; + break; + case _Flags::_Type::__pointer: + break; + default: + __throw_format_error("The format-spec type has a type not supported for a pointer argument"); + } + } +}; /** Helper struct returned from @ref __get_string_alignment. */ template <class _CharT> diff --git contrib/llvm-project/libcxx/include/__function_like.h contrib/llvm-project/libcxx/include/__function_like.h deleted file mode 100644 index 4075355174d9..000000000000 --- contrib/llvm-project/libcxx/include/__function_like.h +++ /dev/null @@ -1,51 +0,0 @@ -// -*- 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 _LIBCPP___ITERATOR_FUNCTION_LIKE_H -#define _LIBCPP___ITERATOR_FUNCTION_LIKE_H - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_RANGES) - -namespace ranges { -// Per [range.iter.ops.general] and [algorithms.requirements], functions in namespace std::ranges -// can't be found by ADL and inhibit ADL when found by unqualified lookup. The easiest way to -// facilitate this is to use function objects. -// -// Since these are still standard library functions, we use `__function_like` to eliminate most of -// the properties that function objects get by default (e.g. semiregularity, addressability), to -// limit the surface area of the unintended public interface, so as to curb the effect of Hyrum's -// law. -struct __function_like { - __function_like() = delete; - __function_like(__function_like const&) = delete; - __function_like& operator=(__function_like const&) = delete; - - void operator&() const = delete; - - struct __tag { }; - -protected: - constexpr explicit __function_like(__tag) noexcept {} - ~__function_like() = default; -}; -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___ITERATOR_FUNCTION_LIKE_H diff --git contrib/llvm-project/libcxx/include/__functional/bind.h contrib/llvm-project/libcxx/include/__functional/bind.h index 0eb95c824664..11a51e5957ee 100644 --- contrib/llvm-project/libcxx/include/__functional/bind.h +++ contrib/llvm-project/libcxx/include/__functional/bind.h @@ -11,8 +11,8 @@ #define _LIBCPP___FUNCTIONAL_BIND_H #include <__config> -#include <__functional/weak_result_type.h> #include <__functional/invoke.h> +#include <__functional/weak_result_type.h> #include <cstddef> #include <tuple> #include <type_traits> @@ -23,18 +23,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template<class _Tp> struct __is_bind_expression : public false_type {}; -template<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_bind_expression - : public __is_bind_expression<typename remove_cv<_Tp>::type> {}; +template<class _Tp> +struct is_bind_expression : _If< + _IsSame<_Tp, typename __uncvref<_Tp>::type>::value, + false_type, + is_bind_expression<typename __uncvref<_Tp>::type> +> {}; #if _LIBCPP_STD_VER > 14 template <class _Tp> inline constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value; #endif -template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {}; -template<class _Tp> struct _LIBCPP_TEMPLATE_VIS is_placeholder - : public __is_placeholder<typename remove_cv<_Tp>::type> {}; +template<class _Tp> +struct is_placeholder : _If< + _IsSame<_Tp, typename __uncvref<_Tp>::type>::value, + integral_constant<int, 0>, + is_placeholder<typename __uncvref<_Tp>::type> +> {}; #if _LIBCPP_STD_VER > 14 template <class _Tp> @@ -73,7 +79,7 @@ _LIBCPP_FUNC_VIS extern const __ph<10> _10; } // namespace placeholders template<int _Np> -struct __is_placeholder<placeholders::__ph<_Np> > +struct is_placeholder<placeholders::__ph<_Np> > : public integral_constant<int, _Np> {}; @@ -304,7 +310,7 @@ public: }; template<class _Fp, class ..._BoundArgs> -struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; +struct is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; template<class _Rp, class _Fp, class ..._BoundArgs> class __bind_r @@ -359,7 +365,7 @@ public: }; template<class _Rp, class _Fp, class ..._BoundArgs> -struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; +struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; template<class _Fp, class ..._BoundArgs> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 diff --git contrib/llvm-project/libcxx/include/__functional/bind_front.h contrib/llvm-project/libcxx/include/__functional/bind_front.h index 86d4594b6571..31397ec5400d 100644 --- contrib/llvm-project/libcxx/include/__functional/bind_front.h +++ contrib/llvm-project/libcxx/include/__functional/bind_front.h @@ -11,8 +11,8 @@ #define _LIBCPP___FUNCTIONAL_BIND_FRONT_H #include <__config> -#include <__functional/perfect_forward.h> #include <__functional/invoke.h> +#include <__functional/perfect_forward.h> #include <type_traits> #include <utility> diff --git contrib/llvm-project/libcxx/include/__functional/function.h contrib/llvm-project/libcxx/include/__functional/function.h index 8336d85adf2e..b6d383ce8459 100644 --- contrib/llvm-project/libcxx/include/__functional/function.h +++ contrib/llvm-project/libcxx/include/__functional/function.h @@ -16,6 +16,7 @@ #include <__functional/invoke.h> #include <__functional/unary_function.h> #include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> #include <__memory/allocator_traits.h> #include <__memory/compressed_pair.h> #include <__memory/shared_ptr.h> @@ -360,7 +361,7 @@ const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { if (__ti == typeid(_Fp)) - return &__f_.__target(); + return _VSTD::addressof(__f_.__target()); return nullptr; } @@ -1392,7 +1393,7 @@ const void* __func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const { if (__ti == typeid(_Fp)) - return &__f_.first(); + return _VSTD::addressof(__f_.first()); return (const void*)0; } diff --git contrib/llvm-project/libcxx/include/__functional/hash.h contrib/llvm-project/libcxx/include/__functional/hash.h index b1a3ad94ae2d..de0c161f47ec 100644 --- contrib/llvm-project/libcxx/include/__functional/hash.h +++ contrib/llvm-project/libcxx/include/__functional/hash.h @@ -16,9 +16,9 @@ #include <__utility/move.h> #include <__utility/pair.h> #include <__utility/swap.h> +#include <cstddef> #include <cstdint> #include <cstring> -#include <cstddef> #include <limits> #include <type_traits> diff --git contrib/llvm-project/libcxx/include/__functional/mem_fn.h contrib/llvm-project/libcxx/include/__functional/mem_fn.h index 1fa070a42cc9..0ec84233439c 100644 --- contrib/llvm-project/libcxx/include/__functional/mem_fn.h +++ contrib/llvm-project/libcxx/include/__functional/mem_fn.h @@ -11,9 +11,9 @@ #define _LIBCPP___FUNCTIONAL_MEM_FN_H #include <__config> -#include <__functional/weak_result_type.h> #include <__functional/binary_function.h> #include <__functional/invoke.h> +#include <__functional/weak_result_type.h> #include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__functional/mem_fun_ref.h contrib/llvm-project/libcxx/include/__functional/mem_fun_ref.h index 4616da0b0748..830936c1b0e5 100644 --- contrib/llvm-project/libcxx/include/__functional/mem_fun_ref.h +++ contrib/llvm-project/libcxx/include/__functional/mem_fun_ref.h @@ -11,8 +11,8 @@ #define _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H #include <__config> -#include <__functional/unary_function.h> #include <__functional/binary_function.h> +#include <__functional/unary_function.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__functional/not_fn.h contrib/llvm-project/libcxx/include/__functional/not_fn.h index 81fe112c88ba..36aab2eb7935 100644 --- contrib/llvm-project/libcxx/include/__functional/not_fn.h +++ contrib/llvm-project/libcxx/include/__functional/not_fn.h @@ -11,8 +11,8 @@ #define _LIBCPP___FUNCTIONAL_NOT_FN_H #include <__config> -#include <__functional/perfect_forward.h> #include <__functional/invoke.h> +#include <__functional/perfect_forward.h> #include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/__functional/reference_wrapper.h contrib/llvm-project/libcxx/include/__functional/reference_wrapper.h index e1e4abd80c23..d04d51568beb 100644 --- contrib/llvm-project/libcxx/include/__functional/reference_wrapper.h +++ contrib/llvm-project/libcxx/include/__functional/reference_wrapper.h @@ -34,25 +34,16 @@ public: private: type* __f_; -#ifndef _LIBCPP_CXX03_LANG static void __fun(_Tp&) _NOEXCEPT; static void __fun(_Tp&&) = delete; -#endif public: - // construct/copy/destroy -#ifdef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - reference_wrapper(type& __f) _NOEXCEPT - : __f_(_VSTD::addressof(__f)) {} -#else - template <class _Up, class = __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) >> + template <class _Up, class = __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(declval<_Up>()))) { type& __f = static_cast<_Up&&>(__u); __f_ = _VSTD::addressof(__f); } -#endif // access _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 @@ -176,7 +167,7 @@ public: #endif // _LIBCPP_CXX03_LANG }; -#if _LIBCPP_STD_VER >= 17 +#if _LIBCPP_STD_VER > 14 template <class _Tp> reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; #endif @@ -194,7 +185,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference_wrapper<_Tp> ref(reference_wrapper<_Tp> __t) _NOEXCEPT { - return _VSTD::ref(__t.get()); + return __t; } template <class _Tp> @@ -210,13 +201,11 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference_wrapper<const _Tp> cref(reference_wrapper<_Tp> __t) _NOEXCEPT { - return _VSTD::cref(__t.get()); + return __t; } -#ifndef _LIBCPP_CXX03_LANG template <class _Tp> void ref(const _Tp&&) = delete; template <class _Tp> void cref(const _Tp&&) = delete; -#endif _LIBCPP_END_NAMESPACE_STD diff --git contrib/llvm-project/libcxx/include/__hash_table contrib/llvm-project/libcxx/include/__hash_table index 126e1884a664..adc732cffb01 100644 --- contrib/llvm-project/libcxx/include/__hash_table +++ contrib/llvm-project/libcxx/include/__hash_table @@ -288,9 +288,7 @@ public: typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } #if _LIBCPP_DEBUG_LEVEL == 2 @@ -310,9 +308,9 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_iterator& operator=(const __hash_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; } return *this; @@ -400,9 +398,7 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } _LIBCPP_INLINE_VISIBILITY @@ -410,7 +406,7 @@ public: : __node_(__x.__node_) { #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__iterator_copy(this, &__x); + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); #endif } @@ -419,7 +415,7 @@ public: __hash_const_iterator(const __hash_const_iterator& __i) : __node_(__i.__node_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -431,9 +427,9 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_iterator& operator=(const __hash_const_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; } return *this; @@ -517,9 +513,7 @@ public: typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } #if _LIBCPP_DEBUG_LEVEL == 2 @@ -529,7 +523,7 @@ public: __bucket_(__i.__bucket_), __bucket_count_(__i.__bucket_count_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -541,9 +535,9 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_local_iterator& operator=(const __hash_local_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; __bucket_ = __i.__bucket_; __bucket_count_ = __i.__bucket_count_; @@ -651,9 +645,7 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } _LIBCPP_INLINE_VISIBILITY @@ -663,7 +655,7 @@ public: __bucket_count_(__x.__bucket_count_) { #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__iterator_copy(this, &__x); + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); #endif } @@ -674,7 +666,7 @@ public: __bucket_(__i.__bucket_), __bucket_count_(__i.__bucket_count_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -686,9 +678,9 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; __bucket_ = __i.__bucket_; __bucket_count_ = __i.__bucket_count_; @@ -1623,7 +1615,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( __u.size() = 0; } #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -2029,11 +2021,9 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( const_iterator __p, __node_pointer __cp) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); if (__p != end() && key_eq()(*__p, __cp->__value_)) { __next_pointer __np = __p.__node_; @@ -2158,11 +2148,9 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( const_iterator __p, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); iterator __r = __node_insert_multi(__p, __h.get()); __h.release(); @@ -2484,12 +2472,12 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) { __next_pointer __np = __p.__node_; + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container erase(iterator) called with an iterator not" + " referring to this container"); + _LIBCPP_DEBUG_ASSERT(__p != end(), + "unordered container erase(iterator) called with a non-dereferenceable iterator"); #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container erase(iterator) called with an iterator not" - " referring to this container"); - _LIBCPP_ASSERT(__p != end(), - "unordered container erase(iterator) called with a non-dereferenceable iterator"); iterator __r(__np, this); #else iterator __r(__np); @@ -2504,14 +2492,12 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_iterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, - "unordered container::erase(iterator, iterator) called with an iterator not" - " referring to this container"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, - "unordered container::erase(iterator, iterator) called with an iterator not" - " referring to this container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, + "unordered container::erase(iterator, iterator) called with an iterator not" + " referring to this container"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, + "unordered container::erase(iterator, iterator) called with an iterator not" + " referring to this container"); for (const_iterator __p = __first; __first != __last; __p = __first) { ++__first; @@ -2741,7 +2727,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = __u.__p1_.first().__ptr(); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } diff --git contrib/llvm-project/libcxx/include/__iterator/advance.h contrib/llvm-project/libcxx/include/__iterator/advance.h index 2236a57936cc..03418979ddbd 100644 --- contrib/llvm-project/libcxx/include/__iterator/advance.h +++ contrib/llvm-project/libcxx/include/__iterator/advance.h @@ -12,13 +12,12 @@ #include <__config> #include <__debug> -#include <__function_like.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> -#include <cstdlib> #include <concepts> +#include <cstdlib> #include <limits> #include <type_traits> @@ -67,17 +66,13 @@ void advance(_InputIter& __i, _Distance __orig_n) { #if !defined(_LIBCPP_HAS_NO_RANGES) -namespace ranges { // [range.iter.op.advance] -// TODO(varconst): rename `__advance_fn` to `__fn`. -struct __advance_fn final : private __function_like { -private: - template <class _Tp> - _LIBCPP_HIDE_FROM_ABI - static constexpr _Tp __magnitude_geq(_Tp __a, _Tp __b) noexcept { - return __a < 0 ? (__a <= __b) : (__a >= __b); - } +namespace ranges { +namespace __advance { + +struct __fn { +private: template <class _Ip> _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) { @@ -97,8 +92,6 @@ private: } public: - constexpr explicit __advance_fn(__tag __x) noexcept : __function_like(__x) {} - // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative. template <input_or_output_iterator _Ip> _LIBCPP_HIDE_FROM_ABI @@ -156,6 +149,12 @@ public: // If `S` and `I` model `sized_sentinel_for<S, I>`: if constexpr (sized_sentinel_for<_Sp, _Ip>) { // If |n| >= |bound - i|, equivalent to `ranges::advance(i, bound)`. + // __magnitude_geq(a, b) returns |a| >= |b|, assuming they have the same sign. + auto __magnitude_geq = [](auto __a, auto __b) { + return __a == 0 ? __b == 0 : + __a > 0 ? __a >= __b : + __a <= __b; + }; if (const auto __M = __bound - __i; __magnitude_geq(__n, __M)) { (*this)(__i, __bound); return __n - __M; @@ -186,7 +185,11 @@ public: } }; -inline constexpr auto advance = __advance_fn(__function_like::__tag()); +} // namespace __advance + +inline namespace __cpo { + inline constexpr auto advance = __advance::__fn{}; +} // namespace __cpo } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git contrib/llvm-project/libcxx/include/__iterator/common_iterator.h contrib/llvm-project/libcxx/include/__iterator/common_iterator.h index 9a142769e55a..605071d70928 100644 --- contrib/llvm-project/libcxx/include/__iterator/common_iterator.h +++ contrib/llvm-project/libcxx/include/__iterator/common_iterator.h @@ -29,6 +29,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if !defined(_LIBCPP_HAS_NO_RANGES) +template<class _Iter> +concept __can_use_postfix_proxy = + constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> && + move_constructible<iter_value_t<_Iter>>; + template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent> requires (!same_as<_Iter, _Sent> && copyable<_Iter>) class common_iterator { @@ -41,7 +46,7 @@ class common_iterator { : __value(_VSTD::move(__x)) {} public: - const iter_value_t<_Iter>* operator->() const { + constexpr const iter_value_t<_Iter>* operator->() const noexcept { return _VSTD::addressof(__value); } }; @@ -54,11 +59,7 @@ class common_iterator { : __value(_VSTD::forward<iter_reference_t<_Iter>>(__x)) {} public: - constexpr static bool __valid_for_iter = - constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> && - move_constructible<iter_value_t<_Iter>>; - - const iter_value_t<_Iter>& operator*() const { + constexpr const iter_value_t<_Iter>& operator*() const noexcept { return __value; } }; @@ -75,7 +76,7 @@ public: requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> constexpr common_iterator(const common_iterator<_I2, _S2>& __other) : __hold_([&]() -> variant<_Iter, _Sent> { - _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Constructed from valueless iterator."); + _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator"); if (__other.__hold_.index() == 0) return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)}; return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)}; @@ -85,7 +86,7 @@ public: requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> && assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&> common_iterator& operator=(const common_iterator<_I2, _S2>& __other) { - _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Assigned from valueless iterator."); + _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator"); auto __idx = __hold_.index(); auto __other_idx = __other.__hold_.index(); @@ -105,18 +106,16 @@ public: return *this; } - decltype(auto) operator*() + constexpr decltype(auto) operator*() { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot dereference sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); return *_VSTD::__unchecked_get<_Iter>(__hold_); } - decltype(auto) operator*() const + constexpr decltype(auto) operator*() const requires __dereferenceable<const _Iter> { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot dereference sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); return *_VSTD::__unchecked_get<_Iter>(__hold_); } @@ -127,9 +126,7 @@ public: is_reference_v<iter_reference_t<_I2>> || constructible_from<iter_value_t<_I2>, iter_reference_t<_I2>>) { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot dereference sentinel. Common iterator not holding an iterator."); - + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { return _VSTD::__unchecked_get<_Iter>(__hold_); } else if constexpr (is_reference_v<iter_reference_t<_Iter>>) { @@ -141,21 +138,18 @@ public: } common_iterator& operator++() { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot increment sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this; } decltype(auto) operator++(int) { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot increment sentinel. Common iterator not holding an iterator."); - + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); if constexpr (forward_iterator<_Iter>) { auto __tmp = *this; ++*this; return __tmp; } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __referenceable; } || - !__postfix_proxy::__valid_for_iter) { + !__can_use_postfix_proxy<_Iter>) { return _VSTD::__unchecked_get<_Iter>(__hold_)++; } else { __postfix_proxy __p(**this); @@ -166,10 +160,9 @@ public: template<class _I2, sentinel_for<_Iter> _S2> requires sentinel_for<_Sent, _I2> - friend bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() && - !__y.__hold_.valueless_by_exception(), - "One or both common_iterators are valueless. (Cannot compare valueless iterators.)"); + friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -185,10 +178,9 @@ public: template<class _I2, sentinel_for<_Iter> _S2> requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2> - friend bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() && - !__y.__hold_.valueless_by_exception(), - "One or both common_iterators are valueless. (Cannot compare valueless iterators.)"); + friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -207,10 +199,9 @@ public: template<sized_sentinel_for<_Iter> _I2, sized_sentinel_for<_Iter> _S2> requires sized_sentinel_for<_Sent, _I2> - friend iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() && - !__y.__hold_.valueless_by_exception(), - "One or both common_iterators are valueless. (Cannot subtract valueless iterators.)"); + friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -227,24 +218,21 @@ public: return _VSTD::__unchecked_get<_Sent>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_); } - friend iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i) + friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i) noexcept(noexcept(ranges::iter_move(declval<const _Iter&>()))) requires input_iterator<_Iter> { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__i.__hold_), - "Cannot iter_move a sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator"); return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_)); } template<indirectly_swappable<_Iter> _I2, class _S2> - friend void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) + friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) noexcept(noexcept(ranges::iter_swap(declval<const _Iter&>(), declval<const _I2&>()))) { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__x.__hold_), - "Cannot swap __y with a sentinel. Common iterator (__x) not holding an iterator."); - _LIBCPP_ASSERT(holds_alternative<_Iter>(__y.__hold_), - "Cannot swap __x with a sentinel. Common iterator (__y) not holding an iterator."); - return ranges::iter_swap( _VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_Iter>(__y.__hold_)); + _LIBCPP_ASSERT(holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + _LIBCPP_ASSERT(holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_)); } }; @@ -271,10 +259,10 @@ struct __arrow_type_or_void { template<class _Iter, class _Sent> requires __common_iter_has_ptr_op<_Iter, _Sent> struct __arrow_type_or_void<_Iter, _Sent> { - using type = decltype(declval<const common_iterator<_Iter, _Sent>>().operator->()); + using type = decltype(declval<const common_iterator<_Iter, _Sent>&>().operator->()); }; -template<class _Iter, class _Sent> +template<input_iterator _Iter, class _Sent> struct iterator_traits<common_iterator<_Iter, _Sent>> { using iterator_concept = _If<forward_iterator<_Iter>, forward_iterator_tag, @@ -288,7 +276,6 @@ struct iterator_traits<common_iterator<_Iter, _Sent>> { using reference = iter_reference_t<_Iter>; }; - #endif // !defined(_LIBCPP_HAS_NO_RANGES) _LIBCPP_END_NAMESPACE_STD diff --git contrib/llvm-project/libcxx/include/__iterator/counted_iterator.h contrib/llvm-project/libcxx/include/__iterator/counted_iterator.h index 55979fe5571e..82d7adcfb02e 100644 --- contrib/llvm-project/libcxx/include/__iterator/counted_iterator.h +++ contrib/llvm-project/libcxx/include/__iterator/counted_iterator.h @@ -13,9 +13,9 @@ #include <__debug> #include <__iterator/concepts.h> #include <__iterator/default_sentinel.h> +#include <__iterator/incrementable_traits.h> #include <__iterator/iter_move.h> #include <__iterator/iter_swap.h> -#include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> #include <__memory/pointer_traits.h> @@ -96,7 +96,7 @@ public: } _LIBCPP_HIDE_FROM_ABI - constexpr const _Iter& base() const& { return __current_; } + constexpr const _Iter& base() const& noexcept { return __current_; } _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return _VSTD::move(__current_); } diff --git contrib/llvm-project/libcxx/include/__iterator/indirectly_comparable.h contrib/llvm-project/libcxx/include/__iterator/indirectly_comparable.h new file mode 100644 index 000000000000..3129b2dcf65e --- /dev/null +++ contrib/llvm-project/libcxx/include/__iterator/indirectly_comparable.h @@ -0,0 +1,30 @@ +// -*- 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 _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H +#define _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H + +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_HAS_NO_RANGES + +template <class _I1, class _I2, class _Rp, class _P1 = identity, class _P2 = identity> +concept indirectly_comparable = + indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; + +#endif // _LIBCPP_HAS_NO_RANGES + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H diff --git contrib/llvm-project/libcxx/include/__iterator/move_iterator.h contrib/llvm-project/libcxx/include/__iterator/move_iterator.h index eac9264df30a..29bac864c275 100644 --- contrib/llvm-project/libcxx/include/__iterator/move_iterator.h +++ contrib/llvm-project/libcxx/include/__iterator/move_iterator.h @@ -12,6 +12,7 @@ #include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -23,19 +24,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Iter> class _LIBCPP_TEMPLATE_VIS move_iterator { -private: - _Iter __i; public: - typedef _Iter iterator_type; +#if _LIBCPP_STD_VER > 17 + typedef input_iterator_tag iterator_concept; +#endif + + typedef _Iter iterator_type; + typedef _If< + __is_cpp17_random_access_iterator<_Iter>::value, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category + > iterator_category; typedef typename iterator_traits<iterator_type>::value_type value_type; typedef typename iterator_traits<iterator_type>::difference_type difference_type; typedef iterator_type pointer; - typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category> iterator_category; -#if _LIBCPP_STD_VER > 17 - typedef input_iterator_tag iterator_concept; -#endif #ifndef _LIBCPP_CXX03_LANG typedef typename iterator_traits<iterator_type>::reference __reference; @@ -48,114 +50,113 @@ public: typedef typename iterator_traits<iterator_type>::reference reference; #endif - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator() : __i() {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator() : __current_() {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - explicit move_iterator(_Iter __x) : __i(__x) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + explicit move_iterator(_Iter __i) : __current_(_VSTD::move(__i)) {} template <class _Up, class = __enable_if_t< - !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value + !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} template <class _Up, class = __enable_if_t< !is_same<_Up, _Iter>::value && - is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter&, _Up const&>::value + is_convertible<const _Up&, _Iter>::value && + is_assignable<_Iter&, const _Up&>::value > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator& operator=(const move_iterator<_Up>& __u) { - __i = __u.base(); + __current_ = __u.base(); return *this; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reference operator*() const { return static_cast<reference>(*__i); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - pointer operator->() const { return __i;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator++() {++__i; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator--() {--__i; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator+ (difference_type __n) const {return move_iterator(__i + __n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator+=(difference_type __n) {__i += __n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator- (difference_type __n) const {return move_iterator(__i - __n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reference operator[](difference_type __n) const { return static_cast<reference>(__i[__n]); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + _Iter base() const { return __current_; } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + reference operator*() const { return static_cast<reference>(*__current_); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + pointer operator->() const { return __current_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator++() { ++__current_; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator--() { --__current_; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } + +private: + _Iter __current_; }; template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() == __y.base(); } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { - return __x.base() < __y.base(); + return __x.base() != __y.base(); } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { - return __x.base() != __y.base(); + return __x.base() < __y.base(); } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() > __y.base(); } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { - return __x.base() >= __y.base(); + return __x.base() <= __y.base(); } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { - return __x.base() <= __y.base(); + return __x.base() >= __y.base(); } #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -auto -operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) --> decltype(__x.base() - __y.base()) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) + -> decltype(__x.base() - __y.base()) { return __x.base() - __y.base(); } #else template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI typename move_iterator<_Iter1>::difference_type operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { @@ -164,7 +165,7 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) #endif template <class _Iter> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator<_Iter> operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) { @@ -172,11 +173,11 @@ operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterato } template <class _Iter> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator<_Iter> make_move_iterator(_Iter __i) { - return move_iterator<_Iter>(__i); + return move_iterator<_Iter>(_VSTD::move(__i)); } _LIBCPP_END_NAMESPACE_STD diff --git contrib/llvm-project/libcxx/include/__iterator/next.h contrib/llvm-project/libcxx/include/__iterator/next.h index d332abfa8e0e..b9bdd6b27e05 100644 --- contrib/llvm-project/libcxx/include/__iterator/next.h +++ contrib/llvm-project/libcxx/include/__iterator/next.h @@ -12,7 +12,6 @@ #include <__config> #include <__debug> -#include <__function_like.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> @@ -38,12 +37,12 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 #if !defined(_LIBCPP_HAS_NO_RANGES) +// [range.iter.op.next] + namespace ranges { -// TODO(varconst): rename `__next_fn` to `__fn`. -struct __next_fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __next_fn(__tag __x) noexcept : __function_like(__x) {} +namespace __next { +struct __fn { template <input_or_output_iterator _Ip> _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { @@ -73,7 +72,11 @@ struct __next_fn final : private __function_like { } }; -inline constexpr auto next = __next_fn(__function_like::__tag()); +} // namespace __next + +inline namespace __cpo { + inline constexpr auto next = __next::__fn{}; +} // namespace __cpo } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git contrib/llvm-project/libcxx/include/__iterator/prev.h contrib/llvm-project/libcxx/include/__iterator/prev.h index 57f2d04a1325..870cbe64eaee 100644 --- contrib/llvm-project/libcxx/include/__iterator/prev.h +++ contrib/llvm-project/libcxx/include/__iterator/prev.h @@ -12,7 +12,6 @@ #include <__config> #include <__debug> -#include <__function_like.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> @@ -37,12 +36,12 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 #if !defined(_LIBCPP_HAS_NO_RANGES) +// [range.iter.op.prev] + namespace ranges { -// TODO(varconst): rename `__prev_fn` to `__fn`. -struct __prev_fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __prev_fn(__tag __x) noexcept : __function_like(__x) {} +namespace __prev { +struct __fn { template <bidirectional_iterator _Ip> _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { @@ -65,7 +64,11 @@ struct __prev_fn final : private __function_like { } }; -inline constexpr auto prev = __prev_fn(__function_like::__tag()); +} // namespace __prev + +inline namespace __cpo { + inline constexpr auto prev = __prev::__fn{}; +} // namespace __cpo } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git contrib/llvm-project/libcxx/include/__iterator/readable_traits.h contrib/llvm-project/libcxx/include/__iterator/readable_traits.h index 90121bea8073..13f323e295ba 100644 --- contrib/llvm-project/libcxx/include/__iterator/readable_traits.h +++ contrib/llvm-project/libcxx/include/__iterator/readable_traits.h @@ -57,14 +57,14 @@ template<__has_member_element_type _Tp> struct indirectly_readable_traits<_Tp> : __cond_value_type<typename _Tp::element_type> {}; -// Pre-emptively applies LWG3541 template<__has_member_value_type _Tp> -requires __has_member_element_type<_Tp> + requires __has_member_element_type<_Tp> struct indirectly_readable_traits<_Tp> {}; + template<__has_member_value_type _Tp> -requires __has_member_element_type<_Tp> && - same_as<remove_cv_t<typename _Tp::element_type>, - remove_cv_t<typename _Tp::value_type>> + requires __has_member_element_type<_Tp> && + same_as<remove_cv_t<typename _Tp::element_type>, + remove_cv_t<typename _Tp::value_type>> struct indirectly_readable_traits<_Tp> : __cond_value_type<typename _Tp::value_type> {}; diff --git contrib/llvm-project/libcxx/include/__iterator/reverse_iterator.h contrib/llvm-project/libcxx/include/__iterator/reverse_iterator.h index d06859ee5f39..449eb529aa98 100644 --- contrib/llvm-project/libcxx/include/__iterator/reverse_iterator.h +++ contrib/llvm-project/libcxx/include/__iterator/reverse_iterator.h @@ -10,9 +10,9 @@ #ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H #define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H -#include <__config> #include <__compare/compare_three_way_result.h> #include <__compare/three_way_comparable.h> +#include <__config> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> @@ -24,13 +24,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Tp, class = void> -struct __is_stashing_iterator : false_type {}; - -template <class _Tp> -struct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type> - : true_type {}; - _LIBCPP_SUPPRESS_DEPRECATED_PUSH template <class _Iter> class _LIBCPP_TEMPLATE_VIS reverse_iterator @@ -48,10 +41,6 @@ private: _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break #endif - static_assert(!__is_stashing_iterator<_Iter>::value, - "The specified iterator type cannot be used with reverse_iterator; " - "Using stashing iterators with reverse_iterator causes undefined behavior"); - protected: _Iter current; public: @@ -88,7 +77,7 @@ public: template <class _Up, class = __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter, _Up const&>::value + is_assignable<_Iter&, _Up const&>::value > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { @@ -113,7 +102,7 @@ public: template <class _Up, class = __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter, _Up const&>::value + is_assignable<_Iter&, _Up const&>::value > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { diff --git contrib/llvm-project/libcxx/include/__iterator/wrap_iter.h contrib/llvm-project/libcxx/include/__iterator/wrap_iter.h index cfcc9857b3fc..d9dbee588896 100644 --- contrib/llvm-project/libcxx/include/__iterator/wrap_iter.h +++ contrib/llvm-project/libcxx/include/__iterator/wrap_iter.h @@ -43,10 +43,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter() _NOEXCEPT : __i() { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } template <class _Up> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(const __wrap_iter<_Up>& __u, @@ -69,9 +66,10 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator=(const __wrap_iter& __x) { - if (this != _VSTD::addressof(__x) && !__libcpp_is_constant_evaluated()) + if (this != _VSTD::addressof(__x)) { - __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); + if (!__libcpp_is_constant_evaluated()) + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); __i = __x.__i; } return *this; @@ -85,29 +83,20 @@ public: #endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator*() const _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable iterator"); return *__i; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 pointer operator->() const _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable iterator"); return _VSTD::__to_address(__i); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator++() _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable iterator"); ++__i; return *this; } @@ -116,11 +105,8 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator--() _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), - "Attempted to decrement a non-decrementable iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement a non-decrementable iterator"); --__i; return *this; } @@ -130,11 +116,8 @@ public: {__wrap_iter __w(*this); __w += __n; return __w;} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n), - "Attempted to add/subtract an iterator outside its valid range"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__addable(this, __n), + "Attempted to add/subtract an iterator outside its valid range"); __i += __n; return *this; } @@ -144,11 +127,8 @@ public: {*this += -__n; return *this;} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator[](difference_type __n) const _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n), - "Attempted to subscript an iterator outside its valid range"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__subscriptable(this, __n), + "Attempted to subscript an iterator outside its valid range"); return __i[__n]; } @@ -189,11 +169,8 @@ template <class _Iter1> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), - "Attempted to compare incomparable iterators"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), + "Attempted to compare incomparable iterators"); return __x.base() < __y.base(); } @@ -201,11 +178,8 @@ template <class _Iter1, class _Iter2> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), - "Attempted to compare incomparable iterators"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), + "Attempted to compare incomparable iterators"); return __x.base() < __y.base(); } @@ -275,11 +249,8 @@ typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT #endif // C++03 { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), - "Attempted to subtract incompatible iterators"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), + "Attempted to subtract incompatible iterators"); return __x.base() - __y.base(); } diff --git contrib/llvm-project/libcxx/include/__locale contrib/llvm-project/libcxx/include/__locale index 2582a90bb578..98445bd2d8f4 100644 --- contrib/llvm-project/libcxx/include/__locale +++ contrib/llvm-project/libcxx/include/__locale @@ -12,13 +12,14 @@ #include <__availability> #include <__config> -#include <string> -#include <memory> -#include <utility> -#include <mutex> -#include <cstdint> #include <cctype> +#include <cstdint> #include <locale.h> +#include <memory> +#include <mutex> +#include <string> +#include <utility> + #if defined(_LIBCPP_MSVCRT_LIKE) # include <cstring> # include <__support/win32/locale_win32.h> @@ -510,6 +511,33 @@ public: # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT +#elif defined(__MVS__) +# if defined(__NATIVE_ASCII_F) + typedef unsigned int mask; + static const mask space = _ISSPACE_A; + static const mask print = _ISPRINT_A; + static const mask cntrl = _ISCNTRL_A; + static const mask upper = _ISUPPER_A; + static const mask lower = _ISLOWER_A; + static const mask alpha = _ISALPHA_A; + static const mask digit = _ISDIGIT_A; + static const mask punct = _ISPUNCT_A; + static const mask xdigit = _ISXDIGIT_A; + static const mask blank = _ISBLANK_A; +# else + typedef unsigned short mask; + static const mask space = __ISSPACE; + static const mask print = __ISPRINT; + static const mask cntrl = __ISCNTRL; + static const mask upper = __ISUPPER; + static const mask lower = __ISLOWER; + static const mask alpha = __ISALPHA; + static const mask digit = __ISDIGIT; + static const mask punct = __ISPUNCT; + static const mask xdigit = __ISXDIGIT; + static const mask blank = __ISBLANK; +# endif + static const mask __regex_word = 0x8000; #else # error unknown rune table for this platform -- do you mean to define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE? #endif @@ -733,6 +761,10 @@ public: static const short* __classic_upper_table() _NOEXCEPT; static const short* __classic_lower_table() _NOEXCEPT; #endif +#if defined(__MVS__) + static const unsigned short* __classic_upper_table() _NOEXCEPT; + static const unsigned short* __classic_lower_table() _NOEXCEPT; +#endif protected: ~ctype(); diff --git contrib/llvm-project/libcxx/include/__memory/construct_at.h contrib/llvm-project/libcxx/include/__memory/construct_at.h index 3b58451c5009..580ce781f482 100644 --- contrib/llvm-project/libcxx/include/__memory/construct_at.h +++ contrib/llvm-project/libcxx/include/__memory/construct_at.h @@ -14,6 +14,7 @@ #include <__debug> #include <__iterator/access.h> #include <__memory/addressof.h> +#include <__memory/voidify.h> #include <__utility/forward.h> #include <type_traits> #include <utility> @@ -31,10 +32,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD template<class _Tp, class ..._Args, class = decltype( ::new (declval<void*>()) _Tp(declval<_Args>()...) )> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) { _LIBCPP_ASSERT(__location, "null pointer given to construct_at"); - return ::new ((void*)__location) _Tp(_VSTD::forward<_Args>(__args)...); + return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...); } #endif @@ -46,7 +47,7 @@ constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) { template <class _ForwardIterator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 -void __destroy(_ForwardIterator, _ForwardIterator); +_ForwardIterator __destroy(_ForwardIterator, _ForwardIterator); template <class _Tp, typename enable_if<!is_array<_Tp>::value, int>::type = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 @@ -66,9 +67,10 @@ void __destroy_at(_Tp* __loc) { template <class _ForwardIterator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 -void __destroy(_ForwardIterator __first, _ForwardIterator __last) { +_ForwardIterator __destroy(_ForwardIterator __first, _ForwardIterator __last) { for (; __first != __last; ++__first) _VSTD::__destroy_at(_VSTD::addressof(*__first)); + return __first; } #if _LIBCPP_STD_VER > 14 @@ -90,7 +92,7 @@ void destroy_at(_Tp* __loc) { template <class _ForwardIterator> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 void destroy(_ForwardIterator __first, _ForwardIterator __last) { - _VSTD::__destroy(_VSTD::move(__first), _VSTD::move(__last)); + (void)_VSTD::__destroy(_VSTD::move(__first), _VSTD::move(__last)); } template <class _ForwardIterator, class _Size> diff --git contrib/llvm-project/libcxx/include/__memory/ranges_construct_at.h contrib/llvm-project/libcxx/include/__memory/ranges_construct_at.h new file mode 100644 index 000000000000..1a72da739682 --- /dev/null +++ contrib/llvm-project/libcxx/include/__memory/ranges_construct_at.h @@ -0,0 +1,124 @@ +// -*- 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 _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H +#define _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H + +#include <__concepts/destructible.h> +#include <__config> +#include <__iterator/incrementable_traits.h> +#include <__iterator/readable_traits.h> +#include <__memory/concepts.h> +#include <__memory/construct_at.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) +namespace ranges { + +// construct_at + +namespace __construct_at { + +struct __fn { + template<class _Tp, class... _Args, class = decltype( + ::new (declval<void*>()) _Tp(declval<_Args>()...) + )> + _LIBCPP_HIDE_FROM_ABI + constexpr _Tp* operator()(_Tp* __location, _Args&& ...__args) const { + return _VSTD::construct_at(__location, _VSTD::forward<_Args>(__args)...); + } +}; + +} // namespace __construct_at + +inline namespace __cpo { + inline constexpr auto construct_at = __construct_at::__fn{}; +} // namespace __cpo + +// destroy_at + +namespace __destroy_at { + +struct __fn { + template <destructible _Tp> + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_Tp* __location) const noexcept { + _VSTD::destroy_at(__location); + } +}; + +} // namespace __destroy_at + +inline namespace __cpo { + inline constexpr auto destroy_at = __destroy_at::__fn{}; +} // namespace __cpo + +// destroy + +namespace __destroy { + +struct __fn { + template <__nothrow_input_iterator _InputIterator, __nothrow_sentinel_for<_InputIterator> _Sentinel> + requires destructible<iter_value_t<_InputIterator>> + _LIBCPP_HIDE_FROM_ABI + constexpr _InputIterator operator()(_InputIterator __first, _Sentinel __last) const noexcept { + return _VSTD::__destroy(_VSTD::move(__first), _VSTD::move(__last)); + } + + template <__nothrow_input_range _InputRange> + requires destructible<range_value_t<_InputRange>> + _LIBCPP_HIDE_FROM_ABI + constexpr borrowed_iterator_t<_InputRange> operator()(_InputRange&& __range) const noexcept { + return (*this)(ranges::begin(__range), ranges::end(__range)); + } +}; + +} // namespace __destroy + +inline namespace __cpo { + inline constexpr auto destroy = __destroy::__fn{}; +} // namespace __cpo + +// destroy_n + +namespace __destroy_n { + +struct __fn { + template <__nothrow_input_iterator _InputIterator> + requires destructible<iter_value_t<_InputIterator>> + _LIBCPP_HIDE_FROM_ABI + constexpr _InputIterator operator()(_InputIterator __first, iter_difference_t<_InputIterator> __n) const noexcept { + return _VSTD::destroy_n(_VSTD::move(__first), __n); + } +}; + +} // namespace __destroy_n + +inline namespace __cpo { + inline constexpr auto destroy_n = __destroy_n::__fn{}; +} // namespace __cpo + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H diff --git contrib/llvm-project/libcxx/include/__memory/ranges_uninitialized_algorithms.h contrib/llvm-project/libcxx/include/__memory/ranges_uninitialized_algorithms.h index 6ec803806c05..6a8f9f070ed7 100644 --- contrib/llvm-project/libcxx/include/__memory/ranges_uninitialized_algorithms.h +++ contrib/llvm-project/libcxx/include/__memory/ranges_uninitialized_algorithms.h @@ -10,10 +10,12 @@ #ifndef _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H #define _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H +#include <__algorithm/in_out_result.h> #include <__concepts/constructible.h> #include <__config> -#include <__function_like.h> +#include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> #include <__memory/concepts.h> @@ -37,10 +39,7 @@ namespace ranges { namespace __uninitialized_default_construct { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel> requires default_initializable<iter_value_t<_ForwardIterator>> @@ -55,25 +54,19 @@ struct __fn final : private __function_like { borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const { return (*this)(ranges::begin(__range), ranges::end(__range)); } - }; } // namespace __uninitialized_default_construct inline namespace __cpo { -inline constexpr auto uninitialized_default_construct = - __uninitialized_default_construct::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_default_construct = __uninitialized_default_construct::__fn{}; } // namespace __cpo // uninitialized_default_construct_n namespace __uninitialized_default_construct_n { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : - __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator> requires default_initializable<iter_value_t<_ForwardIterator>> _ForwardIterator operator()(_ForwardIterator __first, @@ -81,24 +74,19 @@ struct __fn final : private __function_like { using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; return _VSTD::__uninitialized_default_construct_n<_ValueType>(_VSTD::move(__first), __n); } - }; } // namespace __uninitialized_default_construct_n inline namespace __cpo { -inline constexpr auto uninitialized_default_construct_n = - __uninitialized_default_construct_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_default_construct_n = __uninitialized_default_construct_n::__fn{}; } // namespace __cpo // uninitialized_value_construct namespace __uninitialized_value_construct { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel> requires default_initializable<iter_value_t<_ForwardIterator>> @@ -113,24 +101,19 @@ struct __fn final : private __function_like { borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const { return (*this)(ranges::begin(__range), ranges::end(__range)); } - }; } // namespace __uninitialized_value_construct inline namespace __cpo { -inline constexpr auto uninitialized_value_construct = - __uninitialized_value_construct::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_value_construct = __uninitialized_value_construct::__fn{}; } // namespace __cpo // uninitialized_value_construct_n namespace __uninitialized_value_construct_n { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator> requires default_initializable<iter_value_t<_ForwardIterator>> _ForwardIterator operator()(_ForwardIterator __first, @@ -138,24 +121,19 @@ struct __fn final : private __function_like { using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; return _VSTD::__uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n); } - }; } // namespace __uninitialized_value_construct_n inline namespace __cpo { -inline constexpr auto uninitialized_value_construct_n = - __uninitialized_value_construct_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_value_construct_n = __uninitialized_value_construct_n::__fn{}; } // namespace __cpo // uninitialized_fill namespace __uninitialized_fill { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel, class _Tp> @@ -170,23 +148,19 @@ struct __fn final : private __function_like { borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const { return (*this)(ranges::begin(__range), ranges::end(__range), __x); } - }; -} // namespace __uninitialized_fil +} // namespace __uninitialized_fill inline namespace __cpo { -inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn{}; } // namespace __cpo // uninitialized_fill_n namespace __uninitialized_fill_n { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, class _Tp> requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&> _ForwardIterator operator()(_ForwardIterator __first, @@ -195,13 +169,143 @@ struct __fn final : private __function_like { using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; return _VSTD::__uninitialized_fill_n<_ValueType>(_VSTD::move(__first), __n, __x); } - }; } // namespace __uninitialized_fill_n inline namespace __cpo { -inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn{}; +} // namespace __cpo + +// uninitialized_copy + +template <class _InputIterator, class _OutputIterator> +using uninitialized_copy_result = in_out_result<_InputIterator, _OutputIterator>; + +namespace __uninitialized_copy { + +struct __fn { + template <input_iterator _InputIterator, + sentinel_for<_InputIterator> _Sentinel1, + __nothrow_forward_iterator _OutputIterator, + __nothrow_sentinel_for<_OutputIterator> _Sentinel2> + requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> + uninitialized_copy_result<_InputIterator, _OutputIterator> + operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const { + using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; + + auto __result = _VSTD::__uninitialized_copy<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), + _VSTD::move(__ofirst), _VSTD::move(__olast)); + return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; + } + + template <input_range _InputRange, __nothrow_forward_range _OutputRange> + requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>> + uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> + operator()( _InputRange&& __in_range, _OutputRange&& __out_range) const { + return (*this)(ranges::begin(__in_range), ranges::end(__in_range), + ranges::begin(__out_range), ranges::end(__out_range)); + } +}; + +} // namespace __uninitialized_copy + +inline namespace __cpo { + inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn{}; +} // namespace __cpo + +// uninitialized_copy_n + +template <class _InputIterator, class _OutputIterator> +using uninitialized_copy_n_result = in_out_result<_InputIterator, _OutputIterator>; + +namespace __uninitialized_copy_n { + +struct __fn { + template <input_iterator _InputIterator, + __nothrow_forward_iterator _OutputIterator, + __nothrow_sentinel_for<_OutputIterator> _Sentinel> + requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> + uninitialized_copy_n_result<_InputIterator, _OutputIterator> + operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, + _OutputIterator __ofirst, _Sentinel __olast) const { + using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; + auto __result = _VSTD::__uninitialized_copy_n<_ValueType>(_VSTD::move(__ifirst), __n, + _VSTD::move(__ofirst), _VSTD::move(__olast)); + return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; + } +}; + +} // namespace __uninitialized_copy_n + +inline namespace __cpo { + inline constexpr auto uninitialized_copy_n = __uninitialized_copy_n::__fn{}; +} // namespace __cpo + +// uninitialized_move + +template <class _InputIterator, class _OutputIterator> +using uninitialized_move_result = in_out_result<_InputIterator, _OutputIterator>; + +namespace __uninitialized_move { + +struct __fn { + template <input_iterator _InputIterator, + sentinel_for<_InputIterator> _Sentinel1, + __nothrow_forward_iterator _OutputIterator, + __nothrow_sentinel_for<_OutputIterator> _Sentinel2> + requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> + uninitialized_move_result<_InputIterator, _OutputIterator> + operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const { + using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; + auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); }; + auto __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), + _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move); + return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; + } + + template <input_range _InputRange, __nothrow_forward_range _OutputRange> + requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>> + uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> + operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const { + return (*this)(ranges::begin(__in_range), ranges::end(__in_range), + ranges::begin(__out_range), ranges::end(__out_range)); + } +}; + +} // namespace __uninitialized_move + +inline namespace __cpo { + inline constexpr auto uninitialized_move = __uninitialized_move::__fn{}; +} // namespace __cpo + +// uninitialized_move_n + +template <class _InputIterator, class _OutputIterator> +using uninitialized_move_n_result = in_out_result<_InputIterator, _OutputIterator>; + +namespace __uninitialized_move_n { + +struct __fn { + template <input_iterator _InputIterator, + __nothrow_forward_iterator _OutputIterator, + __nothrow_sentinel_for<_OutputIterator> _Sentinel> + requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> + uninitialized_move_n_result<_InputIterator, _OutputIterator> + operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, + _OutputIterator __ofirst, _Sentinel __olast) const { + using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; + auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); }; + auto __result = _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n, + _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move); + return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; + } +}; + +} // namespace __uninitialized_move_n + +inline namespace __cpo { + inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn{}; } // namespace __cpo } // namespace ranges diff --git contrib/llvm-project/libcxx/include/__memory/shared_ptr.h contrib/llvm-project/libcxx/include/__memory/shared_ptr.h index 9c7df8845956..6a4ffc88c866 100644 --- contrib/llvm-project/libcxx/include/__memory/shared_ptr.h +++ contrib/llvm-project/libcxx/include/__memory/shared_ptr.h @@ -12,14 +12,14 @@ #include <__availability> #include <__config> -#include <__functional_base> #include <__functional/binary_function.h> #include <__functional/operations.h> #include <__functional/reference_wrapper.h> +#include <__functional_base> #include <__memory/addressof.h> #include <__memory/allocation_guard.h> -#include <__memory/allocator_traits.h> #include <__memory/allocator.h> +#include <__memory/allocator_traits.h> #include <__memory/compressed_pair.h> #include <__memory/pointer_traits.h> #include <__memory/unique_ptr.h> @@ -28,8 +28,8 @@ #include <cstdlib> // abort #include <iosfwd> #include <stdexcept> -#include <typeinfo> #include <type_traits> +#include <typeinfo> #include <utility> #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) # include <atomic> diff --git contrib/llvm-project/libcxx/include/__memory/uninitialized_algorithms.h contrib/llvm-project/libcxx/include/__memory/uninitialized_algorithms.h index 69132633a48e..40e7c79a51e0 100644 --- contrib/llvm-project/libcxx/include/__memory/uninitialized_algorithms.h +++ contrib/llvm-project/libcxx/include/__memory/uninitialized_algorithms.h @@ -23,52 +23,75 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _InputIterator, class _ForwardIterator> -_ForwardIterator -uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; +// This is a simplified version of C++20 `unreachable_sentinel` that doesn't use concepts and thus can be used in any +// language mode. +struct __unreachable_sentinel { + template <class _Iter> + _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool operator!=(const _Iter&, __unreachable_sentinel) _NOEXCEPT { + return true; + } +}; + +// uninitialized_copy + +template <class _ValueType, class _InputIterator, class _Sentinel1, class _ForwardIterator, class _Sentinel2> +inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> +__uninitialized_copy(_InputIterator __ifirst, _Sentinel1 __ilast, + _ForwardIterator __ofirst, _Sentinel2 __olast) { + _ForwardIterator __idx = __ofirst; #ifndef _LIBCPP_NO_EXCEPTIONS - _ForwardIterator __s = __r; - try - { + try { #endif - for (; __f != __l; ++__f, (void) ++__r) - ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f); + for (; __ifirst != __ilast && __idx != __olast; ++__ifirst, (void)++__idx) + ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst); #ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - for (; __s != __r; ++__s) - __s->~value_type(); - throw; - } + } catch (...) { + _VSTD::__destroy(__ofirst, __idx); + throw; + } #endif - return __r; + + return pair<_InputIterator, _ForwardIterator>(_VSTD::move(__ifirst), _VSTD::move(__idx)); } -template <class _InputIterator, class _Size, class _ForwardIterator> -_ForwardIterator -uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; +template <class _InputIterator, class _ForwardIterator> +_ForwardIterator uninitialized_copy(_InputIterator __ifirst, _InputIterator __ilast, + _ForwardIterator __ofirst) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + auto __result = _VSTD::__uninitialized_copy<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), + _VSTD::move(__ofirst), __unreachable_sentinel()); + return _VSTD::move(__result.second); +} + +// uninitialized_copy_n + +template <class _ValueType, class _InputIterator, class _Size, class _ForwardIterator, class _Sentinel> +inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> +__uninitialized_copy_n(_InputIterator __ifirst, _Size __n, + _ForwardIterator __ofirst, _Sentinel __olast) { + _ForwardIterator __idx = __ofirst; #ifndef _LIBCPP_NO_EXCEPTIONS - _ForwardIterator __s = __r; - try - { + try { #endif - for (; __n > 0; ++__f, (void) ++__r, (void) --__n) - ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f); + for (; __n > 0 && __idx != __olast; ++__ifirst, (void)++__idx, (void)--__n) + ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst); #ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - for (; __s != __r; ++__s) - __s->~value_type(); - throw; - } + } catch (...) { + _VSTD::__destroy(__ofirst, __idx); + throw; + } #endif - return __r; + + return pair<_InputIterator, _ForwardIterator>(_VSTD::move(__ifirst), _VSTD::move(__idx)); +} + +template <class _InputIterator, class _Size, class _ForwardIterator> +inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_copy_n(_InputIterator __ifirst, _Size __n, + _ForwardIterator __ofirst) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + auto __result = _VSTD::__uninitialized_copy_n<_ValueType>(_VSTD::move(__ifirst), __n, _VSTD::move(__ofirst), + __unreachable_sentinel()); + return _VSTD::move(__result.second); } // uninitialized_fill @@ -253,43 +276,71 @@ _ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size return __uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n); } -template <class _InputIt, class _ForwardIt> -inline _LIBCPP_INLINE_VISIBILITY -_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) { - using _Vt = typename iterator_traits<_ForwardIt>::value_type; - auto __idx = __first_res; +// uninitialized_move + +template <class _ValueType, class _InputIterator, class _Sentinel1, class _ForwardIterator, class _Sentinel2, + class _IterMove> +inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> +__uninitialized_move(_InputIterator __ifirst, _Sentinel1 __ilast, + _ForwardIterator __ofirst, _Sentinel2 __olast, _IterMove __iter_move) { + auto __idx = __ofirst; #ifndef _LIBCPP_NO_EXCEPTIONS - try { + try { #endif - for (; __first != __last; ++__idx, (void) ++__first) - ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first)); - return __idx; -#ifndef _LIBCPP_NO_EXCEPTIONS - } catch (...) { - _VSTD::destroy(__first_res, __idx); - throw; + for (; __ifirst != __ilast && __idx != __olast; ++__idx, (void)++__ifirst) { + ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst)); } +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::__destroy(__ofirst, __idx); + throw; + } #endif + + return {_VSTD::move(__ifirst), _VSTD::move(__idx)}; +} + +template <class _InputIterator, class _ForwardIterator> +inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_move(_InputIterator __ifirst, _InputIterator __ilast, + _ForwardIterator __ofirst) { + using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; + auto __iter_move = [](auto&& __iter) -> decltype(auto) { return _VSTD::move(*__iter); }; + + auto __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), + _VSTD::move(__ofirst), __unreachable_sentinel(), __iter_move); + return _VSTD::move(__result.second); } -template <class _InputIt, class _Size, class _ForwardIt> -inline _LIBCPP_INLINE_VISIBILITY -pair<_InputIt, _ForwardIt> -uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) { - using _Vt = typename iterator_traits<_ForwardIt>::value_type; - auto __idx = __first_res; +// uninitialized_move_n + +template <class _ValueType, class _InputIterator, class _Size, class _ForwardIterator, class _Sentinel, class _IterMove> +inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> +__uninitialized_move_n(_InputIterator __ifirst, _Size __n, + _ForwardIterator __ofirst, _Sentinel __olast, _IterMove __iter_move) { + auto __idx = __ofirst; #ifndef _LIBCPP_NO_EXCEPTIONS - try { + try { #endif - for (; __n > 0; ++__idx, (void) ++__first, --__n) - ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first)); - return {__first, __idx}; + for (; __n > 0 && __idx != __olast; ++__idx, (void)++__ifirst, --__n) + ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst)); #ifndef _LIBCPP_NO_EXCEPTIONS - } catch (...) { - _VSTD::destroy(__first_res, __idx); - throw; - } + } catch (...) { + _VSTD::__destroy(__ofirst, __idx); + throw; + } #endif + + return {_VSTD::move(__ifirst), _VSTD::move(__idx)}; +} + +template <class _InputIterator, class _Size, class _ForwardIterator> +inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> +uninitialized_move_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofirst) { + using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; + auto __iter_move = [](auto&& __iter) -> decltype(auto) { return _VSTD::move(*__iter); }; + + return _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n, _VSTD::move(__ofirst), + __unreachable_sentinel(), __iter_move); } #endif // _LIBCPP_STD_VER > 14 diff --git contrib/llvm-project/libcxx/include/__memory/unique_ptr.h contrib/llvm-project/libcxx/include/__memory/unique_ptr.h index 433120394269..e892f3287b93 100644 --- contrib/llvm-project/libcxx/include/__memory/unique_ptr.h +++ contrib/llvm-project/libcxx/include/__memory/unique_ptr.h @@ -11,9 +11,9 @@ #define _LIBCPP___MEMORY_UNIQUE_PTR_H #include <__config> -#include <__functional_base> #include <__functional/hash.h> #include <__functional/operations.h> +#include <__functional_base> #include <__memory/allocator_traits.h> // __pointer #include <__memory/compressed_pair.h> #include <__utility/forward.h> diff --git contrib/llvm-project/libcxx/include/__mutex_base contrib/llvm-project/libcxx/include/__mutex_base index 21e2075603b5..8d8c8af7070c 100644 --- contrib/llvm-project/libcxx/include/__mutex_base +++ contrib/llvm-project/libcxx/include/__mutex_base @@ -13,6 +13,7 @@ #include <__config> #include <__threading_support> #include <chrono> +#include <ratio> #include <system_error> #include <time.h> diff --git contrib/llvm-project/libcxx/include/__random/chi_squared_distribution.h contrib/llvm-project/libcxx/include/__random/chi_squared_distribution.h index 9cf38971bdde..2aa0762a520c 100644 --- contrib/llvm-project/libcxx/include/__random/chi_squared_distribution.h +++ contrib/llvm-project/libcxx/include/__random/chi_squared_distribution.h @@ -11,8 +11,8 @@ #include <__config> #include <__random/gamma_distribution.h> -#include <limits> #include <iosfwd> +#include <limits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/__random/gamma_distribution.h contrib/llvm-project/libcxx/include/__random/gamma_distribution.h index 49d024eafea2..34167e463528 100644 --- contrib/llvm-project/libcxx/include/__random/gamma_distribution.h +++ contrib/llvm-project/libcxx/include/__random/gamma_distribution.h @@ -10,8 +10,8 @@ #define _LIBCPP___RANDOM_GAMMA_DISTRIBUTION_H #include <__config> -#include <__random/uniform_real_distribution.h> #include <__random/exponential_distribution.h> +#include <__random/uniform_real_distribution.h> #include <cmath> #include <iosfwd> #include <limits> diff --git contrib/llvm-project/libcxx/include/__random/lognormal_distribution.h contrib/llvm-project/libcxx/include/__random/lognormal_distribution.h index 752861c3de0c..8fadb5a1e66a 100644 --- contrib/llvm-project/libcxx/include/__random/lognormal_distribution.h +++ contrib/llvm-project/libcxx/include/__random/lognormal_distribution.h @@ -24,6 +24,8 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD +#ifdef _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION + template<class _RealType = double> class _LIBCPP_TEMPLATE_VIS lognormal_distribution { @@ -156,6 +158,140 @@ operator>>(basic_istream<_CharT, _Traits>& __is, return __is >> __x.__p_.__nd_; } +#else // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION + +template<class _RealType = double> +class _LIBCPP_TEMPLATE_VIS lognormal_distribution +{ +public: + // types + typedef _RealType result_type; + + class _LIBCPP_TEMPLATE_VIS param_type + { + result_type __m_; + result_type __s_; + public: + typedef lognormal_distribution distribution_type; + + _LIBCPP_INLINE_VISIBILITY + explicit param_type(result_type __m = 0, result_type __s = 1) + : __m_(__m), __s_(__s) {} + + _LIBCPP_INLINE_VISIBILITY + result_type m() const {return __m_;} + _LIBCPP_INLINE_VISIBILITY + result_type s() const {return __s_;} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const param_type& __x, const param_type& __y) + {return __x.__m_ == __y.__m_ && __x.__s_ == __y.__s_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + normal_distribution<result_type> __nd_; + +public: + // constructor and reset functions +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + lognormal_distribution() : lognormal_distribution(0) {} + _LIBCPP_INLINE_VISIBILITY + explicit lognormal_distribution(result_type __m, result_type __s = 1) + : __nd_(__m, __s) {} +#else + _LIBCPP_INLINE_VISIBILITY + explicit lognormal_distribution(result_type __m = 0, + result_type __s = 1) + : __nd_(__m, __s) {} +#endif + _LIBCPP_INLINE_VISIBILITY + explicit lognormal_distribution(const param_type& __p) + : __nd_(__p.m(), __p.s()) {} + _LIBCPP_INLINE_VISIBILITY + void reset() {__nd_.reset();} + + // generating functions + template<class _URNG> + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g) + { + return _VSTD::exp(__nd_(__g)); + } + + template<class _URNG> + _LIBCPP_INLINE_VISIBILITY + result_type operator()(_URNG& __g, const param_type& __p) + { + typename normal_distribution<result_type>::param_type __pn(__p.m(), __p.s()); + return _VSTD::exp(__nd_(__g, __pn)); + } + + // property functions + _LIBCPP_INLINE_VISIBILITY + result_type m() const {return __nd_.mean();} + _LIBCPP_INLINE_VISIBILITY + result_type s() const {return __nd_.stddev();} + + _LIBCPP_INLINE_VISIBILITY + param_type param() const {return param_type(__nd_.mean(), __nd_.stddev());} + _LIBCPP_INLINE_VISIBILITY + void param(const param_type& __p) + { + typename normal_distribution<result_type>::param_type __pn(__p.m(), __p.s()); + __nd_.param(__pn); + } + + _LIBCPP_INLINE_VISIBILITY + result_type min() const {return 0;} + _LIBCPP_INLINE_VISIBILITY + result_type max() const {return numeric_limits<result_type>::infinity();} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(const lognormal_distribution& __x, + const lognormal_distribution& __y) + {return __x.__nd_ == __y.__nd_;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(const lognormal_distribution& __x, + const lognormal_distribution& __y) + {return !(__x == __y);} + + template <class _CharT, class _Traits, class _RT> + friend + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const lognormal_distribution<_RT>& __x); + + template <class _CharT, class _Traits, class _RT> + friend + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + lognormal_distribution<_RT>& __x); +}; + +template <class _CharT, class _Traits, class _RT> +inline _LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const lognormal_distribution<_RT>& __x) +{ + return __os << __x.__nd_; +} + +template <class _CharT, class _Traits, class _RT> +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + lognormal_distribution<_RT>& __x) +{ + return __is >> __x.__nd_; +} + +#endif // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git contrib/llvm-project/libcxx/include/__random/random_device.h contrib/llvm-project/libcxx/include/__random/random_device.h index 835f726fdbcc..ef11977f9b77 100644 --- contrib/llvm-project/libcxx/include/__random/random_device.h +++ contrib/llvm-project/libcxx/include/__random/random_device.h @@ -27,7 +27,26 @@ class _LIBCPP_TYPE_VIS random_device { #ifdef _LIBCPP_USING_DEV_RANDOM int __f_; +#elif !defined(_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT) +# if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunused-private-field" +# endif + + // Apple platforms used to use the `_LIBCPP_USING_DEV_RANDOM` code path, and now + // use `arc4random()` as of this comment. In order to avoid breaking the ABI, we + // retain the same layout as before. +# if defined(__APPLE__) + int __padding_; // padding to fake the `__f_` field above +# endif + + // ... vendors can add workarounds here if they switch to a different representation ... + +# if defined(__clang__) +# pragma clang diagnostic pop +# endif #endif + public: // types typedef unsigned result_type; diff --git contrib/llvm-project/libcxx/include/__random/seed_seq.h contrib/llvm-project/libcxx/include/__random/seed_seq.h index bf27af6627a5..1a0877995650 100644 --- contrib/llvm-project/libcxx/include/__random/seed_seq.h +++ contrib/llvm-project/libcxx/include/__random/seed_seq.h @@ -31,25 +31,24 @@ public: // types typedef uint32_t result_type; -private: - vector<result_type> __v_; - - template<class _InputIterator> - void init(_InputIterator __first, _InputIterator __last); -public: // constructors _LIBCPP_INLINE_VISIBILITY seed_seq() _NOEXCEPT {} #ifndef _LIBCPP_CXX03_LANG - template<class _Tp> - _LIBCPP_INLINE_VISIBILITY - seed_seq(initializer_list<_Tp> __il) {init(__il.begin(), __il.end());} + template<class _Tp, __enable_if_t<is_integral<_Tp>::value>* = nullptr> + _LIBCPP_INLINE_VISIBILITY + seed_seq(initializer_list<_Tp> __il) { + __init(__il.begin(), __il.end()); + } #endif // _LIBCPP_CXX03_LANG template<class _InputIterator> - _LIBCPP_INLINE_VISIBILITY - seed_seq(_InputIterator __first, _InputIterator __last) - {init(__first, __last);} + _LIBCPP_INLINE_VISIBILITY + seed_seq(_InputIterator __first, _InputIterator __last) { + static_assert(is_integral<typename iterator_traits<_InputIterator>::value_type>::value, + "Mandates: iterator_traits<InputIterator>::value_type is an integer type"); + __init(__first, __last); + } // generating functions template<class _RandomAccessIterator> @@ -68,11 +67,17 @@ public: _LIBCPP_INLINE_VISIBILITY static result_type _Tp(result_type __x) {return __x ^ (__x >> 27);} + +private: + template<class _InputIterator> + void __init(_InputIterator __first, _InputIterator __last); + + vector<result_type> __v_; }; template<class _InputIterator> void -seed_seq::init(_InputIterator __first, _InputIterator __last) +seed_seq::__init(_InputIterator __first, _InputIterator __last) { for (_InputIterator __s = __first; __s != __last; ++__s) __v_.push_back(*__s & 0xFFFFFFFF); diff --git contrib/llvm-project/libcxx/include/__ranges/access.h contrib/llvm-project/libcxx/include/__ranges/access.h index 91dc3055c86d..0b9470fa4017 100644 --- contrib/llvm-project/libcxx/include/__ranges/access.h +++ contrib/llvm-project/libcxx/include/__ranges/access.h @@ -9,6 +9,7 @@ #ifndef _LIBCPP___RANGES_ACCESS_H #define _LIBCPP___RANGES_ACCESS_H +#include <__concepts/class_or_enum.h> #include <__config> #include <__iterator/concepts.h> #include <__iterator/readable_traits.h> @@ -39,6 +40,7 @@ namespace __begin { template <class _Tp> concept __member_begin = __can_borrow<_Tp> && + __workaround_52970<_Tp> && requires(_Tp&& __t) { { _LIBCPP_AUTO_CAST(__t.begin()) } -> input_or_output_iterator; }; @@ -102,6 +104,7 @@ namespace __end { template <class _Tp> concept __member_end = __can_borrow<_Tp> && + __workaround_52970<_Tp> && requires(_Tp&& __t) { typename iterator_t<_Tp>; { _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp>>; @@ -160,20 +163,20 @@ namespace ranges { namespace __cbegin { struct __fn { template <class _Tp> - requires invocable<decltype(ranges::begin), _Tp const&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const - noexcept(noexcept(ranges::begin(_VSTD::as_const(__t)))) - { - return ranges::begin(_VSTD::as_const(__t)); - } + requires is_lvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)))) + -> decltype( ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))) + { return ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)); } template <class _Tp> - requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::begin), _Tp const&&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::begin(static_cast<_Tp const&&>(__t)))) - { - return ranges::begin(static_cast<_Tp const&&>(__t)); - } + requires is_rvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::begin(static_cast<const _Tp&&>(__t)))) + -> decltype( ranges::begin(static_cast<const _Tp&&>(__t))) + { return ranges::begin(static_cast<const _Tp&&>(__t)); } }; } @@ -188,20 +191,20 @@ namespace ranges { namespace __cend { struct __fn { template <class _Tp> - requires invocable<decltype(ranges::end), _Tp const&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const - noexcept(noexcept(ranges::end(_VSTD::as_const(__t)))) - { - return ranges::end(_VSTD::as_const(__t)); - } + requires is_lvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)))) + -> decltype( ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t))) + { return ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)); } template <class _Tp> - requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::end), _Tp const&&> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::end(static_cast<_Tp const&&>(__t)))) - { - return ranges::end(static_cast<_Tp const&&>(__t)); - } + requires is_rvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::end(static_cast<const _Tp&&>(__t)))) + -> decltype( ranges::end(static_cast<const _Tp&&>(__t))) + { return ranges::end(static_cast<const _Tp&&>(__t)); } }; } diff --git contrib/llvm-project/libcxx/include/__ranges/all.h contrib/llvm-project/libcxx/include/__ranges/all.h index ccc77258ba10..90327da81460 100644 --- contrib/llvm-project/libcxx/include/__ranges/all.h +++ contrib/llvm-project/libcxx/include/__ranges/all.h @@ -14,9 +14,9 @@ #include <__iterator/iterator_traits.h> #include <__ranges/access.h> #include <__ranges/concepts.h> +#include <__ranges/owning_view.h> #include <__ranges/range_adaptor.h> #include <__ranges/ref_view.h> -#include <__ranges/subrange.h> #include <__utility/auto_cast.h> #include <__utility/declval.h> #include <__utility/forward.h> @@ -56,12 +56,12 @@ namespace __all { template<class _Tp> requires (!ranges::view<decay_t<_Tp>> && !requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; } && - requires (_Tp&& __t) { ranges::subrange{_VSTD::forward<_Tp>(__t)}; }) + requires (_Tp&& __t) { ranges::owning_view{_VSTD::forward<_Tp>(__t)}; }) [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const - noexcept(noexcept(ranges::subrange{_VSTD::forward<_Tp>(__t)})) + noexcept(noexcept(ranges::owning_view{_VSTD::forward<_Tp>(__t)})) { - return ranges::subrange{_VSTD::forward<_Tp>(__t)}; + return ranges::owning_view{_VSTD::forward<_Tp>(__t)}; } }; } diff --git contrib/llvm-project/libcxx/include/__ranges/concepts.h contrib/llvm-project/libcxx/include/__ranges/concepts.h index bad23c8c4bfb..a9cb15f9f17c 100644 --- contrib/llvm-project/libcxx/include/__ranges/concepts.h +++ contrib/llvm-project/libcxx/include/__ranges/concepts.h @@ -9,6 +9,9 @@ #ifndef _LIBCPP___RANGES_CONCEPTS_H #define _LIBCPP___RANGES_CONCEPTS_H +#include <__concepts/constructible.h> +#include <__concepts/movable.h> +#include <__concepts/same_as.h> #include <__config> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> @@ -20,7 +23,7 @@ #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> #include <__ranges/size.h> -#include <concepts> +#include <initializer_list> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -80,11 +83,11 @@ namespace ranges { movable<_Tp> && enable_view<_Tp>; - template<class _Range> + template <class _Range> concept __simple_view = view<_Range> && range<const _Range> && same_as<iterator_t<_Range>, iterator_t<const _Range>> && - same_as<sentinel_t<_Range>, iterator_t<const _Range>>; + same_as<sentinel_t<_Range>, sentinel_t<const _Range>>; // [range.refinements], other range refinements template <class _Rp, class _Tp> @@ -114,12 +117,20 @@ namespace ranges { template <class _Tp> concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>; - template<class _Tp> + template <class _Tp> + inline constexpr bool __is_std_initializer_list = false; + + template <class _Ep> + inline constexpr bool __is_std_initializer_list<initializer_list<_Ep>> = true; + + template <class _Tp> concept viewable_range = - range<_Tp> && ( - (view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) || - (!view<remove_cvref_t<_Tp>> && borrowed_range<_Tp>) - ); + range<_Tp> && + ((view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) || + (!view<remove_cvref_t<_Tp>> && + (is_lvalue_reference_v<_Tp> || + (movable<remove_reference_t<_Tp>> && !__is_std_initializer_list<remove_cvref_t<_Tp>>)))); + } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git contrib/llvm-project/libcxx/include/__ranges/data.h contrib/llvm-project/libcxx/include/__ranges/data.h index cc151c59f3d7..69dfd479c011 100644 --- contrib/llvm-project/libcxx/include/__ranges/data.h +++ contrib/llvm-project/libcxx/include/__ranges/data.h @@ -9,13 +9,13 @@ #ifndef _LIBCPP___RANGES_DATA_H #define _LIBCPP___RANGES_DATA_H +#include <__concepts/class_or_enum.h> #include <__config> #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> #include <__memory/pointer_traits.h> #include <__ranges/access.h> -#include <__utility/forward.h> -#include <concepts> +#include <__utility/auto_cast.h> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -35,34 +35,33 @@ namespace __data { template <class _Tp> concept __member_data = + __can_borrow<_Tp> && + __workaround_52970<_Tp> && requires(_Tp&& __t) { - { _VSTD::forward<_Tp>(__t) } -> __can_borrow; - { __t.data() } -> __ptr_to_object; + { _LIBCPP_AUTO_CAST(__t.data()) } -> __ptr_to_object; }; template <class _Tp> concept __ranges_begin_invocable = !__member_data<_Tp> && + __can_borrow<_Tp> && requires(_Tp&& __t) { - { _VSTD::forward<_Tp>(__t) } -> __can_borrow; - { ranges::begin(_VSTD::forward<_Tp>(__t)) } -> contiguous_iterator; + { ranges::begin(__t) } -> contiguous_iterator; }; struct __fn { template <__member_data _Tp> - requires __can_borrow<_Tp> _LIBCPP_HIDE_FROM_ABI - constexpr __ptr_to_object auto operator()(_Tp&& __t) const + constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(__t.data())) { return __t.data(); } template<__ranges_begin_invocable _Tp> - requires __can_borrow<_Tp> _LIBCPP_HIDE_FROM_ABI - constexpr __ptr_to_object auto operator()(_Tp&& __t) const - noexcept(noexcept(_VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))))) { - return _VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))); + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(_VSTD::to_address(ranges::begin(__t)))) { + return _VSTD::to_address(ranges::begin(__t)); } }; } @@ -72,6 +71,34 @@ inline namespace __cpo { } // namespace __cpo } // namespace ranges +// [range.prim.cdata] + +namespace ranges { +namespace __cdata { + struct __fn { + template <class _Tp> + requires is_lvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)))) + -> decltype( ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t))) + { return ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)); } + + template <class _Tp> + requires is_rvalue_reference_v<_Tp&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::data(static_cast<const _Tp&&>(__t)))) + -> decltype( ranges::data(static_cast<const _Tp&&>(__t))) + { return ranges::data(static_cast<const _Tp&&>(__t)); } + }; +} + +inline namespace __cpo { + inline constexpr auto cdata = __cdata::__fn{}; +} // namespace __cpo +} // namespace ranges + #endif // !defined(_LIBCPP_HAS_NO_RANGES) _LIBCPP_END_NAMESPACE_STD diff --git contrib/llvm-project/libcxx/include/__ranges/empty.h contrib/llvm-project/libcxx/include/__ranges/empty.h index e8a8aabf4aed..8da0b120f182 100644 --- contrib/llvm-project/libcxx/include/__ranges/empty.h +++ contrib/llvm-project/libcxx/include/__ranges/empty.h @@ -9,6 +9,7 @@ #ifndef _LIBCPP___RANGES_EMPTY_H #define _LIBCPP___RANGES_EMPTY_H +#include <__concepts/class_or_enum.h> #include <__config> #include <__iterator/concepts.h> #include <__ranges/access.h> @@ -28,9 +29,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __empty { template <class _Tp> - concept __member_empty = requires(_Tp&& __t) { - bool(__t.empty()); - }; + concept __member_empty = + __workaround_52970<_Tp> && + requires(_Tp&& __t) { + bool(__t.empty()); + }; template<class _Tp> concept __can_invoke_size = diff --git contrib/llvm-project/libcxx/include/__ranges/empty_view.h contrib/llvm-project/libcxx/include/__ranges/empty_view.h index 4a98a6f324e7..f744dcbe92f4 100644 --- contrib/llvm-project/libcxx/include/__ranges/empty_view.h +++ contrib/llvm-project/libcxx/include/__ranges/empty_view.h @@ -10,6 +10,7 @@ #define _LIBCPP___RANGES_EMPTY_VIEW_H #include <__config> +#include <__ranges/enable_borrowed_range.h> #include <__ranges/view_interface.h> #include <type_traits> @@ -32,6 +33,9 @@ namespace ranges { _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; } _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; } }; + + template<class _Tp> + inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true; } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git contrib/llvm-project/libcxx/include/__ranges/enable_view.h contrib/llvm-project/libcxx/include/__ranges/enable_view.h index a09de11da81e..e1daec046fc0 100644 --- contrib/llvm-project/libcxx/include/__ranges/enable_view.h +++ contrib/llvm-project/libcxx/include/__ranges/enable_view.h @@ -12,6 +12,7 @@ #include <__config> #include <concepts> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -25,8 +26,17 @@ namespace ranges { struct view_base { }; +template<class _Derived> + requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> +class view_interface; + +template<class _Op, class _Yp> + requires is_convertible_v<_Op*, view_interface<_Yp>*> +void __is_derived_from_view_interface(const _Op*, const view_interface<_Yp>*); + template <class _Tp> -inline constexpr bool enable_view = derived_from<_Tp, view_base>; +inline constexpr bool enable_view = derived_from<_Tp, view_base> || + requires { ranges::__is_derived_from_view_interface((_Tp*)nullptr, (_Tp*)nullptr); }; } // end namespace ranges diff --git contrib/llvm-project/libcxx/include/__ranges/owning_view.h contrib/llvm-project/libcxx/include/__ranges/owning_view.h new file mode 100644 index 000000000000..29182d2d8e46 --- /dev/null +++ contrib/llvm-project/libcxx/include/__ranges/owning_view.h @@ -0,0 +1,81 @@ +// -*- 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 _LIBCPP___RANGES_OWNING_VIEW_H +#define _LIBCPP___RANGES_OWNING_VIEW_H + +#include <__concepts/constructible.h> +#include <__concepts/movable.h> +#include <__config> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/data.h> +#include <__ranges/empty.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/size.h> +#include <__ranges/view_interface.h> +#include <__utility/move.h> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + template<range _Rp> + requires movable<_Rp> && (!__is_std_initializer_list<remove_cvref_t<_Rp>>) + class owning_view : public view_interface<owning_view<_Rp>> { + _Rp __r_ = _Rp(); + +public: + owning_view() requires default_initializable<_Rp> = default; + _LIBCPP_HIDE_FROM_ABI constexpr owning_view(_Rp&& __r) : __r_(_VSTD::move(__r)) {} + + owning_view(owning_view&&) = default; + owning_view& operator=(owning_view&&) = default; + + _LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return _VSTD::move(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return _VSTD::move(__r_); } + + _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Rp> begin() { return ranges::begin(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Rp> end() { return ranges::end(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const requires range<const _Rp> { return ranges::begin(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires range<const _Rp> { return ranges::end(__r_); } + + _LIBCPP_HIDE_FROM_ABI constexpr bool empty() requires requires { ranges::empty(__r_); } + { return ranges::empty(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const requires requires { ranges::empty(__r_); } + { return ranges::empty(__r_); } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() requires sized_range<_Rp> + { return ranges::size(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr auto size() const requires sized_range<const _Rp> + { return ranges::size(__r_); } + + _LIBCPP_HIDE_FROM_ABI constexpr auto data() requires contiguous_range<_Rp> + { return ranges::data(__r_); } + _LIBCPP_HIDE_FROM_ABI constexpr auto data() const requires contiguous_range<const _Rp> + { return ranges::data(__r_); } + }; + + template<class _Tp> + inline constexpr bool enable_borrowed_range<owning_view<_Tp>> = enable_borrowed_range<_Tp>; + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANGES_OWNING_VIEW_H diff --git contrib/llvm-project/libcxx/include/__ranges/ref_view.h contrib/llvm-project/libcxx/include/__ranges/ref_view.h index 7567ac48f255..283fa2599bff 100644 --- contrib/llvm-project/libcxx/include/__ranges/ref_view.h +++ contrib/llvm-project/libcxx/include/__ranges/ref_view.h @@ -18,6 +18,7 @@ #include <__ranges/concepts.h> #include <__ranges/data.h> #include <__ranges/empty.h> +#include <__ranges/enable_borrowed_range.h> #include <__ranges/size.h> #include <__ranges/view_interface.h> #include <__utility/forward.h> @@ -74,6 +75,8 @@ public: template<class _Range> ref_view(_Range&) -> ref_view<_Range>; + template<class _Tp> + inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true; } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git contrib/llvm-project/libcxx/include/__ranges/single_view.h contrib/llvm-project/libcxx/include/__ranges/single_view.h index 412fa9b64643..931ce78da7b9 100644 --- contrib/llvm-project/libcxx/include/__ranges/single_view.h +++ contrib/llvm-project/libcxx/include/__ranges/single_view.h @@ -10,8 +10,8 @@ #define _LIBCPP___RANGES_SINGLE_VIEW_H #include <__config> -#include <__ranges/view_interface.h> #include <__ranges/copyable_box.h> +#include <__ranges/view_interface.h> #include <__utility/forward.h> #include <__utility/in_place.h> #include <__utility/move.h> diff --git contrib/llvm-project/libcxx/include/__ranges/size.h contrib/llvm-project/libcxx/include/__ranges/size.h index fc6641cf4887..f3de5a8b8410 100644 --- contrib/llvm-project/libcxx/include/__ranges/size.h +++ contrib/llvm-project/libcxx/include/__ranges/size.h @@ -9,6 +9,7 @@ #ifndef _LIBCPP___RANGES_SIZE_H #define _LIBCPP___RANGES_SIZE_H +#include <__concepts/class_or_enum.h> #include <__config> #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> @@ -41,9 +42,12 @@ namespace __size { concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>; template <class _Tp> - concept __member_size = __size_enabled<_Tp> && requires(_Tp&& __t) { - { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like; - }; + concept __member_size = + __size_enabled<_Tp> && + __workaround_52970<_Tp> && + requires(_Tp&& __t) { + { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like; + }; template <class _Tp> concept __unqualified_size = diff --git contrib/llvm-project/libcxx/include/__ranges/subrange.h contrib/llvm-project/libcxx/include/__ranges/subrange.h index 8e984f2bf06c..14716d1fb0ff 100644 --- contrib/llvm-project/libcxx/include/__ranges/subrange.h +++ contrib/llvm-project/libcxx/include/__ranges/subrange.h @@ -39,13 +39,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if !defined(_LIBCPP_HAS_NO_RANGES) namespace ranges { + template<class _From, class _To> + concept __uses_nonqualification_pointer_conversion = + is_pointer_v<_From> && is_pointer_v<_To> && + !convertible_to<remove_pointer_t<_From>(*)[], remove_pointer_t<_To>(*)[]>; + template<class _From, class _To> concept __convertible_to_non_slicing = convertible_to<_From, _To> && - // If they're both pointers, they must have the same element type. - !(is_pointer_v<decay_t<_From>> && - is_pointer_v<decay_t<_To>> && - __different_from<remove_pointer_t<decay_t<_From>>, remove_pointer_t<decay_t<_To>>>); + !__uses_nonqualification_pointer_conversion<decay_t<_From>, decay_t<_To>>; template<class _Tp> concept __pair_like = diff --git contrib/llvm-project/libcxx/include/__ranges/transform_view.h contrib/llvm-project/libcxx/include/__ranges/transform_view.h index 0f53fbaa7e68..1506e8b2a7fe 100644 --- contrib/llvm-project/libcxx/include/__ranges/transform_view.h +++ contrib/llvm-project/libcxx/include/__ranges/transform_view.h @@ -195,9 +195,7 @@ public: : __parent_(__i.__parent_), __current_(_VSTD::move(__i.__current_)) {} _LIBCPP_HIDE_FROM_ABI - constexpr iterator_t<_Base> base() const& - requires copyable<iterator_t<_Base>> - { + constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; } diff --git contrib/llvm-project/libcxx/include/__ranges/view_interface.h contrib/llvm-project/libcxx/include/__ranges/view_interface.h index 8a1f5d8c9251..c5215cbcb8e3 100644 --- contrib/llvm-project/libcxx/include/__ranges/view_interface.h +++ contrib/llvm-project/libcxx/include/__ranges/view_interface.h @@ -18,7 +18,6 @@ #include <__ranges/access.h> #include <__ranges/concepts.h> #include <__ranges/empty.h> -#include <__ranges/enable_view.h> #include <concepts> #include <type_traits> @@ -40,7 +39,7 @@ void __implicitly_convert_to(type_identity_t<_Tp>) noexcept; template<class _Derived> requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> -class view_interface : public view_base { +class view_interface { _LIBCPP_HIDE_FROM_ABI constexpr _Derived& __derived() noexcept { static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); diff --git contrib/llvm-project/libcxx/include/__string contrib/llvm-project/libcxx/include/__string index 13ff7b35e47d..2249d3a8aec5 100644 --- contrib/llvm-project/libcxx/include/__string +++ contrib/llvm-project/libcxx/include/__string @@ -10,21 +10,21 @@ #ifndef _LIBCPP___STRING #define _LIBCPP___STRING -#include <__config> #include <__algorithm/copy.h> #include <__algorithm/copy_backward.h> #include <__algorithm/copy_n.h> #include <__algorithm/fill_n.h> -#include <__algorithm/find_first_of.h> #include <__algorithm/find_end.h> +#include <__algorithm/find_first_of.h> #include <__algorithm/min.h> +#include <__config> #include <__functional/hash.h> // for __murmur2_or_cityhash #include <__iterator/iterator_traits.h> -#include <cstdio> // for EOF #include <cstdint> // for uint_least16_t +#include <cstdio> // for EOF #include <cstring> // for memcpy -#include <type_traits> // for __libcpp_is_constant_evaluated #include <iosfwd> // for streampos & friends +#include <type_traits> // for __libcpp_is_constant_evaluated #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS # include <cwchar> // for wmemcpy diff --git contrib/llvm-project/libcxx/include/__thread/poll_with_backoff.h contrib/llvm-project/libcxx/include/__thread/poll_with_backoff.h index e1d8a9c90c56..3149a3862890 100644 --- contrib/llvm-project/libcxx/include/__thread/poll_with_backoff.h +++ contrib/llvm-project/libcxx/include/__thread/poll_with_backoff.h @@ -9,6 +9,7 @@ #ifndef _LIBCPP___THREAD_POLL_WITH_BACKOFF_H #define _LIBCPP___THREAD_POLL_WITH_BACKOFF_H +#include <__availability> #include <__config> #include <chrono> diff --git contrib/llvm-project/libcxx/include/__thread/timed_backoff_policy.h contrib/llvm-project/libcxx/include/__thread/timed_backoff_policy.h new file mode 100644 index 000000000000..d85a34071c6d --- /dev/null +++ contrib/llvm-project/libcxx/include/__thread/timed_backoff_policy.h @@ -0,0 +1,45 @@ +// -*- 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 _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H +#define _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H + +#include <__config> + +#ifndef _LIBCPP_HAS_NO_THREADS + +#include <__threading_support> +#include <chrono> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct __libcpp_timed_backoff_policy { + _LIBCPP_INLINE_VISIBILITY + bool operator()(chrono::nanoseconds __elapsed) const + { + if(__elapsed > chrono::milliseconds(128)) + __libcpp_thread_sleep_for(chrono::milliseconds(8)); + else if(__elapsed > chrono::microseconds(64)) + __libcpp_thread_sleep_for(__elapsed / 2); + else if(__elapsed > chrono::microseconds(4)) + __libcpp_thread_yield(); + else + {} // poll + return false; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_HAS_NO_THREADS + +#endif // _LIBCPP___THREAD_TIMED_BACKOFF_POLICY_H diff --git contrib/llvm-project/libcxx/include/__threading_support contrib/llvm-project/libcxx/include/__threading_support index 68f381a62183..bf85d5f5d9f0 100644 --- contrib/llvm-project/libcxx/include/__threading_support +++ contrib/llvm-project/libcxx/include/__threading_support @@ -54,9 +54,6 @@ typedef ::timespec __libcpp_timespec_t; #endif // !defined(_LIBCPP_HAS_NO_THREADS) -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if !defined(_LIBCPP_HAS_NO_THREADS) @@ -252,53 +249,9 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) -struct __libcpp_timed_backoff_policy { - _LIBCPP_INLINE_VISIBILITY - bool operator()(chrono::nanoseconds __elapsed) const - { - if(__elapsed > chrono::milliseconds(128)) - __libcpp_thread_sleep_for(chrono::milliseconds(8)); - else if(__elapsed > chrono::microseconds(64)) - __libcpp_thread_sleep_for(__elapsed / 2); - else if(__elapsed > chrono::microseconds(4)) - __libcpp_thread_yield(); - else - {} // poll - return false; - } -}; - #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) - -namespace __thread_detail { - -_LIBCPP_HIDE_FROM_ABI inline -__libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) -{ - using namespace chrono; - seconds __s = duration_cast<seconds>(__ns); - __libcpp_timespec_t __ts; - typedef decltype(__ts.tv_sec) __ts_sec; - const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); - - if (__s.count() < __ts_sec_max) - { - __ts.tv_sec = static_cast<__ts_sec>(__s.count()); - __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); - } - else - { - __ts.tv_sec = __ts_sec_max; - __ts.tv_nsec = 999999999; // (10^9 - 1) - } - - return __ts; -} - -} // namespace __thread_detail - #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) _LIBCPP_HIDE_FROM_ABI inline @@ -479,7 +432,7 @@ void __libcpp_thread_yield() _LIBCPP_HIDE_FROM_ABI inline void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) { - __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); + __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns); while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); } @@ -664,7 +617,7 @@ void __libcpp_thread_yield() _LIBCPP_HIDE_FROM_ABI inline void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) { - __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); + __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns); thrd_sleep(&__ts, nullptr); } @@ -776,6 +729,4 @@ get_id() _NOEXCEPT _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP_THREADING_SUPPORT diff --git contrib/llvm-project/libcxx/include/__utility/swap.h contrib/llvm-project/libcxx/include/__utility/swap.h index 6c07511686f0..20ec1419fc97 100644 --- contrib/llvm-project/libcxx/include/__utility/swap.h +++ contrib/llvm-project/libcxx/include/__utility/swap.h @@ -12,8 +12,8 @@ #include <__config> #include <__utility/declval.h> #include <__utility/move.h> -#include <type_traits> #include <cstddef> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/algorithm contrib/llvm-project/libcxx/include/algorithm index b28c8cd49890..03b4faaee284 100644 --- contrib/llvm-project/libcxx/include/algorithm +++ contrib/llvm-project/libcxx/include/algorithm @@ -18,6 +18,11 @@ namespace std { +namespace ranges { + template <class I1, class I2> + struct in_in_result; // since C++20 +} + template <class InputIterator, class Predicate> constexpr bool // constexpr in C++20 all_of(InputIterator first, InputIterator last, Predicate pred); @@ -641,19 +646,23 @@ template <class BidirectionalIterator, class Compare> constexpr bool // constexpr in C++20 prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp); +namespace ranges { +// [algorithms.results], algorithm result types +template<class InputIterator, class OutputIterator> + struct in_out_result; +} + } // std */ +#include <__bits> // __libcpp_clz #include <__config> #include <__debug> -#include <__bits> // __libcpp_clz #include <cstddef> #include <cstring> #include <functional> #include <initializer_list> -#include <utility> // needed to provide swap_ranges. -#include <memory> #include <iterator> #include <memory> #include <type_traits> @@ -675,8 +684,8 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/count_if.h> #include <__algorithm/equal.h> #include <__algorithm/equal_range.h> -#include <__algorithm/fill_n.h> #include <__algorithm/fill.h> +#include <__algorithm/fill_n.h> #include <__algorithm/find.h> #include <__algorithm/find_end.h> #include <__algorithm/find_first_of.h> @@ -684,9 +693,11 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/find_if_not.h> #include <__algorithm/for_each.h> #include <__algorithm/for_each_n.h> -#include <__algorithm/generate_n.h> #include <__algorithm/generate.h> +#include <__algorithm/generate_n.h> #include <__algorithm/half_positive.h> +#include <__algorithm/in_in_result.h> +#include <__algorithm/in_out_result.h> #include <__algorithm/includes.h> #include <__algorithm/inplace_merge.h> #include <__algorithm/is_heap.h> @@ -749,8 +760,8 @@ template <class BidirectionalIterator, class Compare> #include <__algorithm/stable_sort.h> #include <__algorithm/swap_ranges.h> #include <__algorithm/transform.h> -#include <__algorithm/unique_copy.h> #include <__algorithm/unique.h> +#include <__algorithm/unique_copy.h> #include <__algorithm/unwrap_iter.h> #include <__algorithm/upper_bound.h> diff --git contrib/llvm-project/libcxx/include/atomic contrib/llvm-project/libcxx/include/atomic index a293b7865dd7..e1820fca351f 100644 --- contrib/llvm-project/libcxx/include/atomic +++ contrib/llvm-project/libcxx/include/atomic @@ -521,6 +521,7 @@ template <class T> #include <__availability> #include <__config> #include <__thread/poll_with_backoff.h> +#include <__thread/timed_backoff_policy.h> #include <cstddef> #include <cstdint> #include <cstring> diff --git contrib/llvm-project/libcxx/include/barrier contrib/llvm-project/libcxx/include/barrier index aef88556a011..c7af46271745 100644 --- contrib/llvm-project/libcxx/include/barrier +++ contrib/llvm-project/libcxx/include/barrier @@ -47,6 +47,7 @@ namespace std #include <__availability> #include <__config> +#include <__thread/timed_backoff_policy.h> #include <atomic> #ifndef _LIBCPP_HAS_NO_TREE_BARRIER # include <memory> diff --git contrib/llvm-project/libcxx/include/bitset contrib/llvm-project/libcxx/include/bitset index 8f538e92e7ff..a5b93f90d40f 100644 --- contrib/llvm-project/libcxx/include/bitset +++ contrib/llvm-project/libcxx/include/bitset @@ -112,14 +112,15 @@ template <size_t N> struct hash<std::bitset<N>>; */ -#include <__config> #include <__bit_reference> +#include <__config> #include <__functional_base> #include <climits> #include <cstddef> #include <iosfwd> #include <stdexcept> #include <string> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/chrono contrib/llvm-project/libcxx/include/chrono index 90c9b0829a1f..eada2b8520e3 100644 --- contrib/llvm-project/libcxx/include/chrono +++ contrib/llvm-project/libcxx/include/chrono @@ -694,2145 +694,20 @@ constexpr chrono::year operator ""y(unsigned lo } // std */ -#include <__availability> +#include <__chrono/calendar.h> +#include <__chrono/convert_to_timespec.h> +#include <__chrono/duration.h> +#include <__chrono/file_clock.h> +#include <__chrono/high_resolution_clock.h> +#include <__chrono/steady_clock.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> #include <__config> #include <compare> -#include <ctime> -#include <limits> -#include <ratio> -#include <type_traits> #include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - -#ifndef _LIBCPP_CXX03_LANG -_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -struct _FilesystemClock; -_LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // !_LIBCPP_CXX03_LANG - -_LIBCPP_BEGIN_NAMESPACE_STD - -namespace chrono -{ - -template <class _Rep, class _Period = ratio<1> > class _LIBCPP_TEMPLATE_VIS duration; - -template <class _Tp> -struct __is_duration : false_type {}; - -template <class _Rep, class _Period> -struct __is_duration<duration<_Rep, _Period> > : true_type {}; - -template <class _Rep, class _Period> -struct __is_duration<const duration<_Rep, _Period> > : true_type {}; - -template <class _Rep, class _Period> -struct __is_duration<volatile duration<_Rep, _Period> > : true_type {}; - -template <class _Rep, class _Period> -struct __is_duration<const volatile duration<_Rep, _Period> > : true_type {}; - -} // namespace chrono - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -struct _LIBCPP_TEMPLATE_VIS common_type<chrono::duration<_Rep1, _Period1>, - chrono::duration<_Rep2, _Period2> > -{ - typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type, - typename __ratio_gcd<_Period1, _Period2>::type> type; -}; - -namespace chrono { - -// duration_cast - -template <class _FromDuration, class _ToDuration, - class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type, - bool = _Period::num == 1, - bool = _Period::den == 1> -struct __duration_cast; - -template <class _FromDuration, class _ToDuration, class _Period> -struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count())); - } -}; - -template <class _FromDuration, class _ToDuration, class _Period> -struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; - return _ToDuration(static_cast<typename _ToDuration::rep>( - static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); - } -}; - -template <class _FromDuration, class _ToDuration, class _Period> -struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; - return _ToDuration(static_cast<typename _ToDuration::rep>( - static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); - } -}; - -template <class _FromDuration, class _ToDuration, class _Period> -struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; - return _ToDuration(static_cast<typename _ToDuration::rep>( - static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) - / static_cast<_Ct>(_Period::den))); - } -}; - -template <class _ToDuration, class _Rep, class _Period> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -duration_cast(const duration<_Rep, _Period>& __fd) -{ - return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd); -} - -template <class _Rep> -struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {}; - -#if _LIBCPP_STD_VER > 14 -template <class _Rep> -inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; -#endif - -template <class _Rep> -struct _LIBCPP_TEMPLATE_VIS duration_values -{ -public: - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} -}; - -#if _LIBCPP_STD_VER > 14 -template <class _ToDuration, class _Rep, class _Period> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -floor(const duration<_Rep, _Period>& __d) -{ - _ToDuration __t = duration_cast<_ToDuration>(__d); - if (__t > __d) - __t = __t - _ToDuration{1}; - return __t; -} - -template <class _ToDuration, class _Rep, class _Period> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -ceil(const duration<_Rep, _Period>& __d) -{ - _ToDuration __t = duration_cast<_ToDuration>(__d); - if (__t < __d) - __t = __t + _ToDuration{1}; - return __t; -} - -template <class _ToDuration, class _Rep, class _Period> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -round(const duration<_Rep, _Period>& __d) -{ - _ToDuration __lower = floor<_ToDuration>(__d); - _ToDuration __upper = __lower + _ToDuration{1}; - auto __lowerDiff = __d - __lower; - auto __upperDiff = __upper - __d; - if (__lowerDiff < __upperDiff) - return __lower; - if (__lowerDiff > __upperDiff) - return __upper; - return __lower.count() & 1 ? __upper : __lower; -} -#endif - -// duration - -template <class _Rep, class _Period> -class _LIBCPP_TEMPLATE_VIS duration -{ - static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); - static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); - static_assert(_Period::num > 0, "duration period must be positive"); - - template <class _R1, class _R2> - struct __no_overflow - { - private: - static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; - static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; - static const intmax_t __n1 = _R1::num / __gcd_n1_n2; - static const intmax_t __d1 = _R1::den / __gcd_d1_d2; - static const intmax_t __n2 = _R2::num / __gcd_n1_n2; - static const intmax_t __d2 = _R2::den / __gcd_d1_d2; - static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); - - template <intmax_t _Xp, intmax_t _Yp, bool __overflow> - struct __mul // __overflow == false - { - static const intmax_t value = _Xp * _Yp; - }; - - template <intmax_t _Xp, intmax_t _Yp> - struct __mul<_Xp, _Yp, true> - { - static const intmax_t value = 1; - }; - - public: - static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); - typedef ratio<__mul<__n1, __d2, !value>::value, - __mul<__n2, __d1, !value>::value> type; - }; - -public: - typedef _Rep rep; - typedef typename _Period::type period; -private: - rep __rep_; -public: - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -#ifndef _LIBCPP_CXX03_LANG - duration() = default; -#else - duration() {} -#endif - - template <class _Rep2> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - explicit duration(const _Rep2& __r, - typename enable_if - < - is_convertible<_Rep2, rep>::value && - (treat_as_floating_point<rep>::value || - !treat_as_floating_point<_Rep2>::value) - >::type* = nullptr) - : __rep_(__r) {} - - // conversions - template <class _Rep2, class _Period2> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - duration(const duration<_Rep2, _Period2>& __d, - typename enable_if - < - __no_overflow<_Period2, period>::value && ( - treat_as_floating_point<rep>::value || - (__no_overflow<_Period2, period>::type::den == 1 && - !treat_as_floating_point<_Rep2>::value)) - >::type* = nullptr) - : __rep_(chrono::duration_cast<duration>(__d).count()) {} - - // observer - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;} - - // arithmetic - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator+() const {return typename common_type<duration>::type(*this);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type<duration>::type operator-() const {return typename common_type<duration>::type(-__rep_);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator++() {++__rep_; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator++(int) {return duration(__rep_++);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator--() {--__rep_; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator--(int) {return duration(__rep_--);} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;} - - // special values - - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values<rep>::zero());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values<rep>::min());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values<rep>::max());} -}; - -typedef duration<long long, nano> nanoseconds; -typedef duration<long long, micro> microseconds; -typedef duration<long long, milli> milliseconds; -typedef duration<long long > seconds; -typedef duration< long, ratio< 60> > minutes; -typedef duration< long, ratio<3600> > hours; -#if _LIBCPP_STD_VER > 17 -typedef duration< int, ratio_multiply<ratio<24>, hours::period>> days; -typedef duration< int, ratio_multiply<ratio<7>, days::period>> weeks; -typedef duration< int, ratio_multiply<ratio<146097, 400>, days::period>> years; -typedef duration< int, ratio_divide<years::period, ratio<12>>> months; -#endif -// Duration == - -template <class _LhsDuration, class _RhsDuration> -struct __duration_eq -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const - { - typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; - return _Ct(__lhs).count() == _Ct(__rhs).count(); - } -}; - -template <class _LhsDuration> -struct __duration_eq<_LhsDuration, _LhsDuration> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const - {return __lhs.count() == __rhs.count();} -}; - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); -} - -// Duration != - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__lhs == __rhs); -} - -// Duration < - -template <class _LhsDuration, class _RhsDuration> -struct __duration_lt -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const - { - typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; - return _Ct(__lhs).count() < _Ct(__rhs).count(); - } -}; - -template <class _LhsDuration> -struct __duration_lt<_LhsDuration, _LhsDuration> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const - {return __lhs.count() < __rhs.count();} -}; - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); -} - -// Duration > - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __rhs < __lhs; -} - -// Duration <= - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__rhs < __lhs); -} - -// Duration >= - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__lhs < __rhs); -} - -// Duration + - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type -operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); -} - -// Duration - - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type -operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); -} - -// Duration * - -template <class _Rep1, class _Period, class _Rep2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, - duration<typename common_type<_Rep1, _Rep2>::type, _Period> ->::type -operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); -} - -template <class _Rep1, class _Period, class _Rep2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value, - duration<typename common_type<_Rep1, _Rep2>::type, _Period> ->::type -operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) -{ - return __d * __s; -} - -// Duration / - -template <class _Rep1, class _Period, class _Rep2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - !__is_duration<_Rep2>::value && - is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, - duration<typename common_type<_Rep1, _Rep2>::type, _Period> ->::type -operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); -} - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename common_type<_Rep1, _Rep2>::type -operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct; - return _Ct(__lhs).count() / _Ct(__rhs).count(); -} - -// Duration % - -template <class _Rep1, class _Period, class _Rep2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - !__is_duration<_Rep2>::value && - is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, - duration<typename common_type<_Rep1, _Rep2>::type, _Period> ->::type -operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); -} - -template <class _Rep1, class _Period1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type -operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); -} - -////////////////////////////////////////////////////////// -///////////////////// time_point ///////////////////////// -////////////////////////////////////////////////////////// - -template <class _Clock, class _Duration = typename _Clock::duration> -class _LIBCPP_TEMPLATE_VIS time_point -{ - static_assert(__is_duration<_Duration>::value, - "Second template parameter of time_point must be a std::chrono::duration"); -public: - typedef _Clock clock; - typedef _Duration duration; - typedef typename duration::rep rep; - typedef typename duration::period period; -private: - duration __d_; - -public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {} - - // conversions - template <class _Duration2> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - time_point(const time_point<clock, _Duration2>& t, - typename enable_if - < - is_convertible<_Duration2, duration>::value - >::type* = nullptr) - : __d_(t.time_since_epoch()) {} - - // observer - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;} - - // arithmetic - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} - - // special values - - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());} -}; - -} // namespace chrono - -template <class _Clock, class _Duration1, class _Duration2> -struct _LIBCPP_TEMPLATE_VIS common_type<chrono::time_point<_Clock, _Duration1>, - chrono::time_point<_Clock, _Duration2> > -{ - typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; -}; - -namespace chrono { - -template <class _ToDuration, class _Clock, class _Duration> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -time_point<_Clock, _ToDuration> -time_point_cast(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); -} - -#if _LIBCPP_STD_VER > 14 -template <class _ToDuration, class _Clock, class _Duration> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - time_point<_Clock, _ToDuration> ->::type -floor(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{floor<_ToDuration>(__t.time_since_epoch())}; -} - -template <class _ToDuration, class _Clock, class _Duration> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - time_point<_Clock, _ToDuration> ->::type -ceil(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{ceil<_ToDuration>(__t.time_since_epoch())}; -} - -template <class _ToDuration, class _Clock, class _Duration> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - time_point<_Clock, _ToDuration> ->::type -round(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{round<_ToDuration>(__t.time_since_epoch())}; -} - -template <class _Rep, class _Period> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - numeric_limits<_Rep>::is_signed, - duration<_Rep, _Period> ->::type -abs(duration<_Rep, _Period> __d) -{ - return __d >= __d.zero() ? +__d : -__d; -} -#endif - -// time_point == - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() == __rhs.time_since_epoch(); -} - -// time_point != - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__lhs == __rhs); -} - -// time_point < - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() < __rhs.time_since_epoch(); -} - -// time_point > - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __rhs < __lhs; -} - -// time_point <= - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__rhs < __lhs); -} - -// time_point >= - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -bool -operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__lhs < __rhs); -} - -// time_point operator+(time_point x, duration y); - -template <class _Clock, class _Duration1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> -operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; - return _Tr (__lhs.time_since_epoch() + __rhs); -} - -// time_point operator+(duration x, time_point y); - -template <class _Rep1, class _Period1, class _Clock, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type> -operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __rhs + __lhs; -} - -// time_point operator-(time_point x, duration y); - -template <class _Clock, class _Duration1, class _Rep2, class _Period2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> -operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; - return _Ret(__lhs.time_since_epoch() -__rhs); -} - -// duration operator-(time_point x, time_point y); - -template <class _Clock, class _Duration1, class _Duration2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -typename common_type<_Duration1, _Duration2>::type -operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() - __rhs.time_since_epoch(); -} - -////////////////////////////////////////////////////////// -/////////////////////// clocks /////////////////////////// -////////////////////////////////////////////////////////// - -class _LIBCPP_TYPE_VIS system_clock -{ -public: - typedef microseconds duration; - typedef duration::rep rep; - typedef duration::period period; - typedef chrono::time_point<system_clock> time_point; - static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; - - static time_point now() _NOEXCEPT; - static time_t to_time_t (const time_point& __t) _NOEXCEPT; - static time_point from_time_t(time_t __t) _NOEXCEPT; -}; - -#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK -class _LIBCPP_TYPE_VIS steady_clock -{ -public: - typedef nanoseconds duration; - typedef duration::rep rep; - typedef duration::period period; - typedef chrono::time_point<steady_clock, duration> time_point; - static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true; - - static time_point now() _NOEXCEPT; -}; - -typedef steady_clock high_resolution_clock; -#else -typedef system_clock high_resolution_clock; -#endif - -#if _LIBCPP_STD_VER > 17 -// [time.clock.file], type file_clock -using file_clock = _VSTD_FS::_FilesystemClock; - -template<class _Duration> -using file_time = time_point<file_clock, _Duration>; - - -template <class _Duration> -using sys_time = time_point<system_clock, _Duration>; -using sys_seconds = sys_time<seconds>; -using sys_days = sys_time<days>; - -struct local_t {}; -template<class Duration> -using local_time = time_point<local_t, Duration>; -using local_seconds = local_time<seconds>; -using local_days = local_time<days>; - - -struct last_spec { explicit last_spec() = default; }; - -class day { -private: - unsigned char __d; -public: - day() = default; - explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {} - inline constexpr day& operator++() noexcept { ++__d; return *this; } - inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } - inline constexpr day& operator--() noexcept { --__d; return *this; } - inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; } - constexpr day& operator+=(const days& __dd) noexcept; - constexpr day& operator-=(const days& __dd) noexcept; - explicit inline constexpr operator unsigned() const noexcept { return __d; } - inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; } - }; - - -inline constexpr -bool operator==(const day& __lhs, const day& __rhs) noexcept -{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } - -inline constexpr -bool operator!=(const day& __lhs, const day& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const day& __lhs, const day& __rhs) noexcept -{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } - -inline constexpr -bool operator> (const day& __lhs, const day& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const day& __lhs, const day& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const day& __lhs, const day& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr -day operator+ (const day& __lhs, const days& __rhs) noexcept -{ return day(static_cast<unsigned>(__lhs) + __rhs.count()); } - -inline constexpr -day operator+ (const days& __lhs, const day& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -day operator- (const day& __lhs, const days& __rhs) noexcept -{ return __lhs + -__rhs; } - -inline constexpr -days operator-(const day& __lhs, const day& __rhs) noexcept -{ return days(static_cast<int>(static_cast<unsigned>(__lhs)) - - static_cast<int>(static_cast<unsigned>(__rhs))); } - -inline constexpr day& day::operator+=(const days& __dd) noexcept -{ *this = *this + __dd; return *this; } - -inline constexpr day& day::operator-=(const days& __dd) noexcept -{ *this = *this - __dd; return *this; } - - -class month { -private: - unsigned char __m; -public: - month() = default; - explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {} - inline constexpr month& operator++() noexcept { ++__m; return *this; } - inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } - inline constexpr month& operator--() noexcept { --__m; return *this; } - inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } - constexpr month& operator+=(const months& __m1) noexcept; - constexpr month& operator-=(const months& __m1) noexcept; - explicit inline constexpr operator unsigned() const noexcept { return __m; } - inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; } -}; - - -inline constexpr -bool operator==(const month& __lhs, const month& __rhs) noexcept -{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } - -inline constexpr -bool operator!=(const month& __lhs, const month& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const month& __lhs, const month& __rhs) noexcept -{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } - -inline constexpr -bool operator> (const month& __lhs, const month& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const month& __lhs, const month& __rhs) noexcept -{ return !(__rhs < __lhs); } - -inline constexpr -bool operator>=(const month& __lhs, const month& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr -month operator+ (const month& __lhs, const months& __rhs) noexcept -{ - auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1); - auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; - return month{static_cast<unsigned>(__mu - __yr * 12 + 1)}; -} - -inline constexpr -month operator+ (const months& __lhs, const month& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -month operator- (const month& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } - -inline constexpr -months operator-(const month& __lhs, const month& __rhs) noexcept -{ - auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs); - return months(__dm <= 11 ? __dm : __dm + 12); -} - -inline constexpr month& month::operator+=(const months& __dm) noexcept -{ *this = *this + __dm; return *this; } - -inline constexpr month& month::operator-=(const months& __dm) noexcept -{ *this = *this - __dm; return *this; } - - -class year { -private: - short __y; -public: - year() = default; - explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {} - - inline constexpr year& operator++() noexcept { ++__y; return *this; } - inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; } - inline constexpr year& operator--() noexcept { --__y; return *this; } - inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; } - constexpr year& operator+=(const years& __dy) noexcept; - constexpr year& operator-=(const years& __dy) noexcept; - inline constexpr year operator+() const noexcept { return *this; } - inline constexpr year operator-() const noexcept { return year{-__y}; } - - inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); } - explicit inline constexpr operator int() const noexcept { return __y; } - constexpr bool ok() const noexcept; - static inline constexpr year min() noexcept { return year{-32767}; } - static inline constexpr year max() noexcept { return year{ 32767}; } -}; - - -inline constexpr -bool operator==(const year& __lhs, const year& __rhs) noexcept -{ return static_cast<int>(__lhs) == static_cast<int>(__rhs); } - -inline constexpr -bool operator!=(const year& __lhs, const year& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const year& __lhs, const year& __rhs) noexcept -{ return static_cast<int>(__lhs) < static_cast<int>(__rhs); } - -inline constexpr -bool operator> (const year& __lhs, const year& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const year& __lhs, const year& __rhs) noexcept -{ return !(__rhs < __lhs); } - -inline constexpr -bool operator>=(const year& __lhs, const year& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr -year operator+ (const year& __lhs, const years& __rhs) noexcept -{ return year(static_cast<int>(__lhs) + __rhs.count()); } - -inline constexpr -year operator+ (const years& __lhs, const year& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year operator- (const year& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } - -inline constexpr -years operator-(const year& __lhs, const year& __rhs) noexcept -{ return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; } - - -inline constexpr year& year::operator+=(const years& __dy) noexcept -{ *this = *this + __dy; return *this; } - -inline constexpr year& year::operator-=(const years& __dy) noexcept -{ *this = *this - __dy; return *this; } - -inline constexpr bool year::ok() const noexcept -{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); } - -class weekday_indexed; -class weekday_last; - -class weekday { -private: - unsigned char __wd; - static constexpr unsigned char __weekday_from_days(int __days) noexcept; -public: - weekday() = default; - inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {} - inline constexpr weekday(const sys_days& __sysd) noexcept - : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {} - inline explicit constexpr weekday(const local_days& __locd) noexcept - : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {} - - inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; } - inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } - inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; } - inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } - constexpr weekday& operator+=(const days& __dd) noexcept; - constexpr weekday& operator-=(const days& __dd) noexcept; - inline constexpr unsigned c_encoding() const noexcept { return __wd; } - inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; } - inline constexpr bool ok() const noexcept { return __wd <= 6; } - constexpr weekday_indexed operator[](unsigned __index) const noexcept; - constexpr weekday_last operator[](last_spec) const noexcept; -}; - - -// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days -inline constexpr -unsigned char weekday::__weekday_from_days(int __days) noexcept -{ - return static_cast<unsigned char>( - static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) - ); -} - -inline constexpr -bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept -{ return __lhs.c_encoding() == __rhs.c_encoding(); } - -inline constexpr -bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept -{ return __lhs.c_encoding() < __rhs.c_encoding(); } - -inline constexpr -bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__lhs < __rhs); } - -constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept -{ - auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count(); - auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; - return weekday{static_cast<unsigned>(__mu - __yr * 7)}; -} - -constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept -{ return __rhs + __lhs; } - -constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept -{ return __lhs + -__rhs; } - -constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept -{ - const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); - const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; - return days{__wdu - __wk * 7}; -} - -inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept -{ *this = *this + __dd; return *this; } - -inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept -{ *this = *this - __dd; return *this; } - - -class weekday_indexed { -private: - chrono::weekday __wd; - unsigned char __idx; -public: - weekday_indexed() = default; - inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept - : __wd{__wdval}, __idx(__idxval) {} - inline constexpr chrono::weekday weekday() const noexcept { return __wd; } - inline constexpr unsigned index() const noexcept { return __idx; } - inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; } -}; - -inline constexpr -bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept -{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } - -inline constexpr -bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept -{ return !(__lhs == __rhs); } - - -class weekday_last { -private: - chrono::weekday __wd; -public: - explicit constexpr weekday_last(const chrono::weekday& __val) noexcept - : __wd{__val} {} - constexpr chrono::weekday weekday() const noexcept { return __wd; } - constexpr bool ok() const noexcept { return __wd.ok(); } -}; - -inline constexpr -bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept -{ return __lhs.weekday() == __rhs.weekday(); } - -inline constexpr -bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } - -inline constexpr -weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } - - -inline constexpr last_spec last{}; -inline constexpr weekday Sunday{0}; -inline constexpr weekday Monday{1}; -inline constexpr weekday Tuesday{2}; -inline constexpr weekday Wednesday{3}; -inline constexpr weekday Thursday{4}; -inline constexpr weekday Friday{5}; -inline constexpr weekday Saturday{6}; - -inline constexpr month January{1}; -inline constexpr month February{2}; -inline constexpr month March{3}; -inline constexpr month April{4}; -inline constexpr month May{5}; -inline constexpr month June{6}; -inline constexpr month July{7}; -inline constexpr month August{8}; -inline constexpr month September{9}; -inline constexpr month October{10}; -inline constexpr month November{11}; -inline constexpr month December{12}; - - -class month_day { -private: - chrono::month __m; - chrono::day __d; -public: - month_day() = default; - constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept - : __m{__mval}, __d{__dval} {} - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::day day() const noexcept { return __d; } - constexpr bool ok() const noexcept; -}; - -inline constexpr -bool month_day::ok() const noexcept -{ - if (!__m.ok()) return false; - const unsigned __dval = static_cast<unsigned>(__d); - if (__dval < 1 || __dval > 31) return false; - if (__dval <= 29) return true; -// Now we've got either 30 or 31 - const unsigned __mval = static_cast<unsigned>(__m); - if (__mval == 2) return false; - if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) - return __dval == 30; - return true; -} - -inline constexpr -bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } - -inline constexpr -bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -month_day operator/(const month& __lhs, const day& __rhs) noexcept -{ return month_day{__lhs, __rhs}; } - -constexpr -month_day operator/(const day& __lhs, const month& __rhs) noexcept -{ return __rhs / __lhs; } - -inline constexpr -month_day operator/(const month& __lhs, int __rhs) noexcept -{ return __lhs / day(__rhs); } - -constexpr -month_day operator/(int __lhs, const day& __rhs) noexcept -{ return month(__lhs) / __rhs; } - -constexpr -month_day operator/(const day& __lhs, int __rhs) noexcept -{ return month(__rhs) / __lhs; } - - -inline constexpr -bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept -{ return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); } - -inline constexpr -bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept -{ return !(__lhs < __rhs); } - - - -class month_day_last { -private: - chrono::month __m; -public: - explicit constexpr month_day_last(const chrono::month& __val) noexcept - : __m{__val} {} - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr bool ok() const noexcept { return __m.ok(); } -}; - -inline constexpr -bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return __lhs.month() == __rhs.month(); } - -inline constexpr -bool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return __lhs.month() < __rhs.month(); } - -inline constexpr -bool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr -month_day_last operator/(const month& __lhs, last_spec) noexcept -{ return month_day_last{__lhs}; } - -inline constexpr -month_day_last operator/(last_spec, const month& __rhs) noexcept -{ return month_day_last{__rhs}; } - -inline constexpr -month_day_last operator/(int __lhs, last_spec) noexcept -{ return month_day_last{month(__lhs)}; } - -inline constexpr -month_day_last operator/(last_spec, int __rhs) noexcept -{ return month_day_last{month(__rhs)}; } - - -class month_weekday { -private: - chrono::month __m; - chrono::weekday_indexed __wdi; -public: - month_weekday() = default; - constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept - : __m{__mval}, __wdi{__wdival} {} - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } - inline constexpr bool ok() const noexcept { return __m.ok() && __wdi.ok(); } -}; - -inline constexpr -bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } - -inline constexpr -bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept -{ return month_weekday{__lhs, __rhs}; } - -inline constexpr -month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept -{ return month_weekday{month(__lhs), __rhs}; } - -inline constexpr -month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept -{ return month_weekday{__rhs, __lhs}; } - -inline constexpr -month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept -{ return month_weekday{month(__rhs), __lhs}; } - - -class month_weekday_last { - chrono::month __m; - chrono::weekday_last __wdl; - public: - constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept - : __m{__mval}, __wdl{__wdlval} {} - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } - inline constexpr bool ok() const noexcept { return __m.ok() && __wdl.ok(); } -}; - -inline constexpr -bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } - -inline constexpr -bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - - -inline constexpr -month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept -{ return month_weekday_last{__lhs, __rhs}; } - -inline constexpr -month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept -{ return month_weekday_last{month(__lhs), __rhs}; } - -inline constexpr -month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept -{ return month_weekday_last{__rhs, __lhs}; } - -inline constexpr -month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept -{ return month_weekday_last{month(__rhs), __lhs}; } - - -class year_month { - chrono::year __y; - chrono::month __m; -public: - year_month() = default; - constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept - : __y{__yval}, __m{__mval} {} - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; } - inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; } - inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; } - inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; } - inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); } -}; - -inline constexpr -year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; } - -inline constexpr -year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; } - -inline constexpr -bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); } - -inline constexpr -bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept -{ return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); } - -inline constexpr -bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept -{ return !(__lhs < __rhs); } - -constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept -{ - int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count(); - const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12; - __dmi = __dmi - __dy * 12 + 1; - return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi)); -} - -constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept -{ return __rhs + __lhs; } - -constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept -{ return (__lhs.year() + __rhs) / __lhs.month(); } - -constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept -{ return __rhs + __lhs; } - -constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept -{ return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); } - -constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } - -constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } - -class year_month_day_last; - -class year_month_day { -private: - chrono::year __y; - chrono::month __m; - chrono::day __d; -public: - year_month_day() = default; - inline constexpr year_month_day( - const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept - : __y{__yval}, __m{__mval}, __d{__dval} {} - constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; - inline constexpr year_month_day(const sys_days& __sysd) noexcept - : year_month_day(__from_days(__sysd.time_since_epoch())) {} - inline explicit constexpr year_month_day(const local_days& __locd) noexcept - : year_month_day(__from_days(__locd.time_since_epoch())) {} - - constexpr year_month_day& operator+=(const months& __dm) noexcept; - constexpr year_month_day& operator-=(const months& __dm) noexcept; - constexpr year_month_day& operator+=(const years& __dy) noexcept; - constexpr year_month_day& operator-=(const years& __dy) noexcept; - - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::day day() const noexcept { return __d; } - inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - - constexpr bool ok() const noexcept; - - static constexpr year_month_day __from_days(days __d) noexcept; - constexpr days __to_days() const noexcept; -}; - - -// https://howardhinnant.github.io/date_algorithms.html#civil_from_days -inline constexpr -year_month_day -year_month_day::__from_days(days __d) noexcept -{ - static_assert(numeric_limits<unsigned>::digits >= 18, ""); - static_assert(numeric_limits<int>::digits >= 20 , ""); - const int __z = __d.count() + 719468; - const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; - const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096] - const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] - const int __yr = static_cast<int>(__yoe) + __era * 400; - const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] - const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] - const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] - const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] - return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; -} - -// https://howardhinnant.github.io/date_algorithms.html#days_from_civil -inline constexpr days year_month_day::__to_days() const noexcept -{ - static_assert(numeric_limits<unsigned>::digits >= 18, ""); - static_assert(numeric_limits<int>::digits >= 20 , ""); - - const int __yr = static_cast<int>(__y) - (__m <= February); - const unsigned __mth = static_cast<unsigned>(__m); - const unsigned __dy = static_cast<unsigned>(__d); - - const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; - const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399] - const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] - const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] - return days{__era * 146097 + static_cast<int>(__doe) - 719468}; -} - -inline constexpr -bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } - -inline constexpr -bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ - if (__lhs.year() < __rhs.year()) return true; - if (__lhs.year() > __rhs.year()) return false; - if (__lhs.month() < __rhs.month()) return true; - if (__lhs.month() > __rhs.month()) return false; - return __lhs.day() < __rhs.day(); -} - -inline constexpr -bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr -year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept -{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; } - -inline constexpr -year_month_day operator/(const year_month& __lhs, int __rhs) noexcept -{ return __lhs / day(__rhs); } - -inline constexpr -year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept -{ return __lhs / __rhs.month() / __rhs.day(); } - -inline constexpr -year_month_day operator/(int __lhs, const month_day& __rhs) noexcept -{ return year(__lhs) / __rhs; } - -inline constexpr -year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } - -inline constexpr -year_month_day operator/(const month_day& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } - - -inline constexpr -year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept -{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); } - -inline constexpr -year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } - -inline constexpr -year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept -{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); } - -inline constexpr -year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } - -inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } - -class year_month_day_last { -private: - chrono::year __y; - chrono::month_day_last __mdl; -public: - constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept - : __y{__yval}, __mdl{__mdlval} {} - - constexpr year_month_day_last& operator+=(const months& __m) noexcept; - constexpr year_month_day_last& operator-=(const months& __m) noexcept; - constexpr year_month_day_last& operator+=(const years& __y) noexcept; - constexpr year_month_day_last& operator-=(const years& __y) noexcept; - - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __mdl.month(); } - inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; } - constexpr chrono::day day() const noexcept; - inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } - inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } - inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); } -}; - -inline constexpr -chrono::day year_month_day_last::day() const noexcept -{ - constexpr chrono::day __d[] = - { - chrono::day(31), chrono::day(28), chrono::day(31), - chrono::day(30), chrono::day(31), chrono::day(30), - chrono::day(31), chrono::day(31), chrono::day(30), - chrono::day(31), chrono::day(30), chrono::day(31) - }; - return (month() != February || !__y.is_leap()) && month().ok() ? - __d[static_cast<unsigned>(month()) - 1] : chrono::day{29}; -} - -inline constexpr -bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } - -inline constexpr -bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ - if (__lhs.year() < __rhs.year()) return true; - if (__lhs.year() > __rhs.year()) return false; - return __lhs.month_day_last() < __rhs.month_day_last(); -} - -inline constexpr -bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs < __lhs; } - -inline constexpr -bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__rhs < __lhs);} - -inline constexpr -bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__lhs < __rhs); } - -inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept -{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; } - -inline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept -{ return year_month_day_last{__lhs, __rhs}; } - -inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept -{ return year_month_day_last{year{__lhs}, __rhs}; } - -inline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } - -inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept -{ return year{__rhs} / __lhs; } - - -inline constexpr -year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / last; } - -inline constexpr -year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } - -inline constexpr -year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept -{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; } - -inline constexpr -year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } - -inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } - -inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept - : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {} - -inline constexpr bool year_month_day::ok() const noexcept -{ - if (!__y.ok() || !__m.ok()) return false; - return chrono::day{1} <= __d && __d <= (__y / __m / last).day(); -} - -class year_month_weekday { - chrono::year __y; - chrono::month __m; - chrono::weekday_indexed __wdi; -public: - year_month_weekday() = default; - constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, - const chrono::weekday_indexed& __wdival) noexcept - : __y{__yval}, __m{__mval}, __wdi{__wdival} {} - constexpr year_month_weekday(const sys_days& __sysd) noexcept - : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} - inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept - : year_month_weekday(__from_days(__locd.time_since_epoch())) {} - constexpr year_month_weekday& operator+=(const months& m) noexcept; - constexpr year_month_weekday& operator-=(const months& m) noexcept; - constexpr year_month_weekday& operator+=(const years& y) noexcept; - constexpr year_month_weekday& operator-=(const years& y) noexcept; - - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::weekday weekday() const noexcept { return __wdi.weekday(); } - inline constexpr unsigned index() const noexcept { return __wdi.index(); } - inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } - - inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - inline constexpr bool ok() const noexcept - { - if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false; - if (__wdi.index() <= 4) return true; - auto __nth_weekday_day = - __wdi.weekday() - - chrono::weekday{static_cast<sys_days>(__y / __m / 1)} + - days{(__wdi.index() - 1) * 7 + 1}; - return static_cast<unsigned>(__nth_weekday_day.count()) <= - static_cast<unsigned>((__y / __m / last).day()); - } - - static constexpr year_month_weekday __from_days(days __d) noexcept; - constexpr days __to_days() const noexcept; -}; - -inline constexpr -year_month_weekday year_month_weekday::__from_days(days __d) noexcept -{ - const sys_days __sysd{__d}; - const chrono::weekday __wd = chrono::weekday(__sysd); - const year_month_day __ymd = year_month_day(__sysd); - return year_month_weekday{__ymd.year(), __ymd.month(), - __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]}; -} - -inline constexpr -days year_month_weekday::__to_days() const noexcept -{ - const sys_days __sysd = sys_days(__y/__m/1); - return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7})) - .time_since_epoch(); -} - -inline constexpr -bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } - -inline constexpr -bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept -{ return !(__lhs == __rhs); } - -inline constexpr -year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept -{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } - -inline constexpr -year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept -{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; } - -inline constexpr -year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept -{ return year(__lhs) / __rhs; } - -inline constexpr -year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } - -inline constexpr -year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } - - -inline constexpr -year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); } - -inline constexpr -year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } - -inline constexpr -year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept -{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; } - -inline constexpr -year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } - - -inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } - -class year_month_weekday_last { -private: - chrono::year __y; - chrono::month __m; - chrono::weekday_last __wdl; -public: - constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval, - const chrono::weekday_last& __wdlval) noexcept - : __y{__yval}, __m{__mval}, __wdl{__wdlval} {} - constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; - constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; - constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; - constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; - - inline constexpr chrono::year year() const noexcept { return __y; } - inline constexpr chrono::month month() const noexcept { return __m; } - inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); } - inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } - inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); } - - constexpr days __to_days() const noexcept; - -}; - -inline constexpr -days year_month_weekday_last::__to_days() const noexcept -{ - const sys_days __last = sys_days{__y/__m/last}; - return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch(); - -} - -inline constexpr -bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } - -inline constexpr -bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - - -inline constexpr -year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept -{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } - -inline constexpr -year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept -{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; } - -inline constexpr -year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept -{ return year(__lhs) / __rhs; } - -inline constexpr -year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } - -inline constexpr -year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } - - -inline constexpr -year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); } - -inline constexpr -year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } - -inline constexpr -year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept -{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; } - -inline constexpr -year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __rhs + __lhs; } - -inline constexpr -year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } - -inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } - - -template <class _Duration> -class hh_mm_ss -{ -private: - static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); - using __CommonType = common_type_t<_Duration, chrono::seconds>; - - static constexpr uint64_t __pow10(unsigned __exp) - { - uint64_t __ret = 1; - for (unsigned __i = 0; __i < __exp; ++__i) - __ret *= 10U; - return __ret; - } - - static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) - { - if (__n >= 2 && __d != 0 && __w < 19) - return 1 + __width(__n, __d % __n * 10, __w+1); - return 0; - } - -public: - static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ? - __width(__CommonType::period::den) : 6u; - using precision = duration<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>; - - constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} - - constexpr explicit hh_mm_ss(_Duration __d) noexcept : - __is_neg(__d < _Duration(0)), - __h(duration_cast<chrono::hours> (abs(__d))), - __m(duration_cast<chrono::minutes>(abs(__d) - hours())), - __s(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())), - __f(duration_cast<precision> (abs(__d) - hours() - minutes() - seconds())) - {} - - constexpr bool is_negative() const noexcept { return __is_neg; } - constexpr chrono::hours hours() const noexcept { return __h; } - constexpr chrono::minutes minutes() const noexcept { return __m; } - constexpr chrono::seconds seconds() const noexcept { return __s; } - constexpr precision subseconds() const noexcept { return __f; } - - constexpr precision to_duration() const noexcept - { - auto __dur = __h + __m + __s + __f; - return __is_neg ? -__dur : __dur; - } - - constexpr explicit operator precision() const noexcept { return to_duration(); } - -private: - bool __is_neg; - chrono::hours __h; - chrono::minutes __m; - chrono::seconds __s; - precision __f; -}; - -constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } -constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } - -constexpr hours make12(const hours& __h) noexcept -{ - if (__h == hours( 0)) return hours(12); - else if (__h <= hours(12)) return __h; - else return __h - hours(12); -} - -constexpr hours make24(const hours& __h, bool __is_pm) noexcept -{ - if (__is_pm) - return __h == hours(12) ? __h : __h + hours(12); - else - return __h == hours(12) ? hours(0) : __h; -} - -#endif // _LIBCPP_STD_VER > 17 -} // namespace chrono - -#if _LIBCPP_STD_VER > 11 -// Suffixes for duration literals [time.duration.literals] -inline namespace literals -{ - inline namespace chrono_literals - { - - constexpr chrono::hours operator""h(unsigned long long __h) - { - return chrono::hours(static_cast<chrono::hours::rep>(__h)); - } - - constexpr chrono::duration<long double, ratio<3600,1>> operator""h(long double __h) - { - return chrono::duration<long double, ratio<3600,1>>(__h); - } - - - constexpr chrono::minutes operator""min(unsigned long long __m) - { - return chrono::minutes(static_cast<chrono::minutes::rep>(__m)); - } - - constexpr chrono::duration<long double, ratio<60,1>> operator""min(long double __m) - { - return chrono::duration<long double, ratio<60,1>> (__m); - } - - - constexpr chrono::seconds operator""s(unsigned long long __s) - { - return chrono::seconds(static_cast<chrono::seconds::rep>(__s)); - } - - constexpr chrono::duration<long double> operator""s(long double __s) - { - return chrono::duration<long double> (__s); - } - - - constexpr chrono::milliseconds operator""ms(unsigned long long __ms) - { - return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms)); - } - - constexpr chrono::duration<long double, milli> operator""ms(long double __ms) - { - return chrono::duration<long double, milli>(__ms); - } - - - constexpr chrono::microseconds operator""us(unsigned long long __us) - { - return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us)); - } - - constexpr chrono::duration<long double, micro> operator""us(long double __us) - { - return chrono::duration<long double, micro> (__us); - } - - - constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) - { - return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns)); - } - - constexpr chrono::duration<long double, nano> operator""ns(long double __ns) - { - return chrono::duration<long double, nano> (__ns); - } - -#if _LIBCPP_STD_VER > 17 - constexpr chrono::day operator ""d(unsigned long long __d) noexcept - { - return chrono::day(static_cast<unsigned>(__d)); - } - - constexpr chrono::year operator ""y(unsigned long long __y) noexcept - { - return chrono::year(static_cast<int>(__y)); - } -#endif -} // namespace chrono_literals -} // namespace literals - -namespace chrono { // hoist the literals into namespace std::chrono - using namespace literals::chrono_literals; -} // namespace chrono - -#endif - -_LIBCPP_END_NAMESPACE_STD - -#ifndef _LIBCPP_CXX03_LANG -_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -struct _FilesystemClock { -#if !defined(_LIBCPP_HAS_NO_INT128) - typedef __int128_t rep; - typedef nano period; -#else - typedef long long rep; - typedef nano period; -#endif - - typedef chrono::duration<rep, period> duration; - typedef chrono::time_point<_FilesystemClock> time_point; - - _LIBCPP_EXPORTED_FROM_ABI - static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; - - _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept; - -#if _LIBCPP_STD_VER > 17 - template <class _Duration> - _LIBCPP_HIDE_FROM_ABI - static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { - return chrono::sys_time<_Duration>(__t.time_since_epoch()); - } - - template <class _Duration> - _LIBCPP_HIDE_FROM_ABI - static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { - return chrono::file_time<_Duration>(__t.time_since_epoch()); - } -#endif // _LIBCPP_STD_VER > 17 -}; -_LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // !_LIBCPP_CXX03_LANG - -_LIBCPP_POP_MACROS - #endif // _LIBCPP_CHRONO diff --git contrib/llvm-project/libcxx/include/cmath contrib/llvm-project/libcxx/include/cmath index b5c332c81ad6..8bd55542ed92 100644 --- contrib/llvm-project/libcxx/include/cmath +++ contrib/llvm-project/libcxx/include/cmath @@ -306,8 +306,8 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept #include <__config> #include <math.h> -#include <version> #include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -636,6 +636,23 @@ lerp(double __a, double __b, double __t) _NOEXCEPT { return __ler constexpr long double lerp(long double __a, long double __b, long double __t) _NOEXCEPT { return __lerp(__a, __b, __t); } +template <class _A1, class _A2, class _A3> +inline _LIBCPP_HIDE_FROM_ABI +constexpr typename enable_if_t +< + is_arithmetic<_A1>::value && + is_arithmetic<_A2>::value && + is_arithmetic<_A3>::value, + __promote<_A1, _A2, _A3> +>::type +lerp(_A1 __a, _A2 __b, _A3 __t) noexcept +{ + typedef typename __promote<_A1, _A2, _A3>::type __result_type; + static_assert(!(_IsSame<_A1, __result_type>::value && + _IsSame<_A2, __result_type>::value && + _IsSame<_A3, __result_type>::value)); + return __lerp((__result_type)__a, (__result_type)__b, (__result_type)__t); +} #endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git contrib/llvm-project/libcxx/include/codecvt contrib/llvm-project/libcxx/include/codecvt index 60d3db882c03..74839d199686 100644 --- contrib/llvm-project/libcxx/include/codecvt +++ contrib/llvm-project/libcxx/include/codecvt @@ -56,6 +56,7 @@ class codecvt_utf8_utf16 #include <__config> #include <__locale> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/compare contrib/llvm-project/libcxx/include/compare index 5d07ebaf2fbd..d686b5a369f2 100644 --- contrib/llvm-project/libcxx/include/compare +++ contrib/llvm-project/libcxx/include/compare @@ -145,6 +145,7 @@ namespace std { #include <__compare/three_way_comparable.h> #include <__compare/weak_order.h> #include <__config> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/condition_variable contrib/llvm-project/libcxx/include/condition_variable index 0569e2254d1d..ecec3ea8c017 100644 --- contrib/llvm-project/libcxx/include/condition_variable +++ contrib/llvm-project/libcxx/include/condition_variable @@ -109,6 +109,7 @@ public: #include <__config> #include <__mutex_base> #include <memory> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/coroutine contrib/llvm-project/libcxx/include/coroutine index 4e140ab3fed7..6e83fe285bc7 100644 --- contrib/llvm-project/libcxx/include/coroutine +++ contrib/llvm-project/libcxx/include/coroutine @@ -40,8 +40,8 @@ struct suspend_always; #include <__config> #include <__coroutine/coroutine_handle.h> -#include <__coroutine/noop_coroutine_handle.h> #include <__coroutine/coroutine_traits.h> +#include <__coroutine/noop_coroutine_handle.h> #include <__coroutine/trivial_awaitables.h> #include <version> diff --git contrib/llvm-project/libcxx/include/execution contrib/llvm-project/libcxx/include/execution index c1debcb72ff1..417b11b103a2 100644 --- contrib/llvm-project/libcxx/include/execution +++ contrib/llvm-project/libcxx/include/execution @@ -11,6 +11,7 @@ #define _LIBCPP_EXECUTION #include <__config> +#include <version> #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 # include <__pstl_execution> diff --git contrib/llvm-project/libcxx/include/experimental/__memory contrib/llvm-project/libcxx/include/experimental/__memory index bd9bf95e5933..33027793895d 100644 --- contrib/llvm-project/libcxx/include/experimental/__memory +++ contrib/llvm-project/libcxx/include/experimental/__memory @@ -10,11 +10,11 @@ #ifndef _LIBCPP_EXPERIMENTAL___MEMORY #define _LIBCPP_EXPERIMENTAL___MEMORY +#include <__functional_base> #include <__memory/allocator_arg_t.h> #include <__memory/uses_allocator.h> #include <experimental/__config> #include <experimental/utility> // for erased_type -#include <__functional_base> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/experimental/algorithm contrib/llvm-project/libcxx/include/experimental/algorithm index bcf372cafd7a..a7fa18ff5dde 100644 --- contrib/llvm-project/libcxx/include/experimental/algorithm +++ contrib/llvm-project/libcxx/include/experimental/algorithm @@ -31,12 +31,11 @@ ForwardIterator search(ForwardIterator first, ForwardIterator last, */ -#include <experimental/__config> +#include <__debug> #include <algorithm> +#include <experimental/__config> #include <type_traits> -#include <__debug> - #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif diff --git contrib/llvm-project/libcxx/include/experimental/coroutine contrib/llvm-project/libcxx/include/experimental/coroutine index 16b4028765bc..4b53e4b62b40 100644 --- contrib/llvm-project/libcxx/include/experimental/coroutine +++ contrib/llvm-project/libcxx/include/experimental/coroutine @@ -45,13 +45,13 @@ template <class P> struct hash<coroutine_handle<P>>; */ +#include <__debug> +#include <cstddef> #include <experimental/__config> -#include <new> -#include <type_traits> #include <functional> #include <memory> // for hash<T*> -#include <cstddef> -#include <__debug> +#include <new> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/experimental/deque contrib/llvm-project/libcxx/include/experimental/deque index 594ddff22f98..41c25d95b9a0 100644 --- contrib/llvm-project/libcxx/include/experimental/deque +++ contrib/llvm-project/libcxx/include/experimental/deque @@ -28,8 +28,8 @@ namespace pmr { */ -#include <experimental/__config> #include <deque> +#include <experimental/__config> #include <experimental/memory_resource> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git contrib/llvm-project/libcxx/include/experimental/forward_list contrib/llvm-project/libcxx/include/experimental/forward_list index 6781424cf2c6..590bef0283a2 100644 --- contrib/llvm-project/libcxx/include/experimental/forward_list +++ contrib/llvm-project/libcxx/include/experimental/forward_list @@ -29,8 +29,8 @@ namespace pmr { */ #include <experimental/__config> -#include <forward_list> #include <experimental/memory_resource> +#include <forward_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/experimental/functional contrib/llvm-project/libcxx/include/experimental/functional index bcff51e8056f..8977c6354355 100644 --- contrib/llvm-project/libcxx/include/experimental/functional +++ contrib/llvm-project/libcxx/include/experimental/functional @@ -86,16 +86,15 @@ inline namespace fundamentals_v1 { */ +#include <__debug> #include <__memory/uses_allocator.h> +#include <algorithm> +#include <array> #include <experimental/__config> #include <functional> -#include <algorithm> #include <type_traits> -#include <vector> -#include <array> #include <unordered_map> - -#include <__debug> +#include <vector> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -104,7 +103,6 @@ inline namespace fundamentals_v1 { _LIBCPP_PUSH_MACROS #include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_LFTS #if _LIBCPP_STD_VER > 11 diff --git contrib/llvm-project/libcxx/include/experimental/iterator contrib/llvm-project/libcxx/include/experimental/iterator index 9da08a0cff9d..ab1f54e35eb9 100644 --- contrib/llvm-project/libcxx/include/experimental/iterator +++ contrib/llvm-project/libcxx/include/experimental/iterator @@ -53,8 +53,8 @@ namespace std { */ #include <__memory/addressof.h> -#include <__utility/move.h> #include <__utility/forward.h> +#include <__utility/move.h> #include <experimental/__config> #include <iterator> diff --git contrib/llvm-project/libcxx/include/experimental/list contrib/llvm-project/libcxx/include/experimental/list index 099d80fd8db5..be43e60f49ad 100644 --- contrib/llvm-project/libcxx/include/experimental/list +++ contrib/llvm-project/libcxx/include/experimental/list @@ -29,8 +29,8 @@ namespace pmr { */ #include <experimental/__config> -#include <list> #include <experimental/memory_resource> +#include <list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/experimental/map contrib/llvm-project/libcxx/include/experimental/map index 27ff7e862e27..704626eed674 100644 --- contrib/llvm-project/libcxx/include/experimental/map +++ contrib/llvm-project/libcxx/include/experimental/map @@ -34,8 +34,8 @@ namespace pmr { */ #include <experimental/__config> -#include <map> #include <experimental/memory_resource> +#include <map> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/experimental/memory_resource contrib/llvm-project/libcxx/include/experimental/memory_resource index 71a4f51c50e5..47bb8c58c8de 100644 --- contrib/llvm-project/libcxx/include/experimental/memory_resource +++ contrib/llvm-project/libcxx/include/experimental/memory_resource @@ -64,18 +64,18 @@ namespace pmr { */ +#include <__debug> +#include <__tuple> +#include <cstddef> +#include <cstdlib> #include <experimental/__config> #include <experimental/__memory> #include <limits> #include <memory> #include <new> #include <stdexcept> -#include <__tuple> #include <type_traits> #include <utility> -#include <cstddef> -#include <cstdlib> -#include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/experimental/propagate_const contrib/llvm-project/libcxx/include/experimental/propagate_const index 12376dcec242..deb4ba98a7fa 100644 --- contrib/llvm-project/libcxx/include/experimental/propagate_const +++ contrib/llvm-project/libcxx/include/experimental/propagate_const @@ -107,19 +107,18 @@ */ #include <experimental/__config> +#include <functional> +#include <type_traits> +#include <utility> + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif #if _LIBCPP_STD_VER > 11 -#include <type_traits> -#include <utility> -#include <functional> - _LIBCPP_BEGIN_NAMESPACE_LFTS_V2 - template <class _Tp> class propagate_const; diff --git contrib/llvm-project/libcxx/include/experimental/regex contrib/llvm-project/libcxx/include/experimental/regex index ced0e950a127..5bb3dccf9387 100644 --- contrib/llvm-project/libcxx/include/experimental/regex +++ contrib/llvm-project/libcxx/include/experimental/regex @@ -36,9 +36,9 @@ namespace pmr { */ #include <experimental/__config> -#include <regex> -#include <experimental/string> #include <experimental/memory_resource> +#include <experimental/string> +#include <regex> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/experimental/set contrib/llvm-project/libcxx/include/experimental/set index 891510bbb8d9..12b2ac23b81a 100644 --- contrib/llvm-project/libcxx/include/experimental/set +++ contrib/llvm-project/libcxx/include/experimental/set @@ -34,8 +34,8 @@ namespace pmr { */ #include <experimental/__config> -#include <set> #include <experimental/memory_resource> +#include <set> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/experimental/simd contrib/llvm-project/libcxx/include/experimental/simd index 1f17ee96f0b5..475155512d76 100644 --- contrib/llvm-project/libcxx/include/experimental/simd +++ contrib/llvm-project/libcxx/include/experimental/simd @@ -649,10 +649,10 @@ public: */ -#include <experimental/__config> #include <algorithm> #include <array> #include <cstddef> +#include <experimental/__config> #include <functional> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -689,7 +689,7 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> { friend struct simd_mask; public: - _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }; + _Tp __get(size_t __index) const noexcept { return __storage_[__index]; } void __set(size_t __index, _Tp __val) noexcept { __storage_[__index] = __val; } @@ -706,7 +706,7 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> { friend struct simd_mask; public: - _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; }; + _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; } void __set(size_t __index, _Tp __val) noexcept { (&__storage_)[__index] = __val; } @@ -770,7 +770,7 @@ struct __vec_ext_traits { _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 29); \ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 30); \ _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 31); \ - _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 32); + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 32) _LIBCPP_SPECIALIZE_VEC_EXT_32(char); _LIBCPP_SPECIALIZE_VEC_EXT_32(char16_t); @@ -808,7 +808,7 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> { friend struct simd_mask; public: - _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }; + _Tp __get(size_t __index) const noexcept { return __storage_[__index]; } void __set(size_t __index, _Tp __val) noexcept { __storage_[__index] = __val; } diff --git contrib/llvm-project/libcxx/include/experimental/string contrib/llvm-project/libcxx/include/experimental/string index b881fcf3af1c..1643e84c5a0c 100644 --- contrib/llvm-project/libcxx/include/experimental/string +++ contrib/llvm-project/libcxx/include/experimental/string @@ -38,8 +38,8 @@ namespace pmr { */ #include <experimental/__config> -#include <string> #include <experimental/memory_resource> +#include <string> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/experimental/unordered_map contrib/llvm-project/libcxx/include/experimental/unordered_map index fc8cc7f77bf0..80905e68ef36 100644 --- contrib/llvm-project/libcxx/include/experimental/unordered_map +++ contrib/llvm-project/libcxx/include/experimental/unordered_map @@ -40,8 +40,8 @@ namespace pmr { */ #include <experimental/__config> -#include <unordered_map> #include <experimental/memory_resource> +#include <unordered_map> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/experimental/unordered_set contrib/llvm-project/libcxx/include/experimental/unordered_set index 39342da5f679..f09b0bd57d9f 100644 --- contrib/llvm-project/libcxx/include/experimental/unordered_set +++ contrib/llvm-project/libcxx/include/experimental/unordered_set @@ -34,8 +34,8 @@ namespace pmr { */ #include <experimental/__config> -#include <unordered_set> #include <experimental/memory_resource> +#include <unordered_set> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/experimental/vector contrib/llvm-project/libcxx/include/experimental/vector index a22698ef7ce4..4d31d1ccd85b 100644 --- contrib/llvm-project/libcxx/include/experimental/vector +++ contrib/llvm-project/libcxx/include/experimental/vector @@ -29,8 +29,8 @@ namespace pmr { */ #include <experimental/__config> -#include <vector> #include <experimental/memory_resource> +#include <vector> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/ext/__hash contrib/llvm-project/libcxx/include/ext/__hash index 2f998ee40a93..f6e7a486f6b6 100644 --- contrib/llvm-project/libcxx/include/ext/__hash +++ contrib/llvm-project/libcxx/include/ext/__hash @@ -13,8 +13,8 @@ #pragma GCC system_header #include <__string> -#include <string> #include <cstring> +#include <string> namespace __gnu_cxx { diff --git contrib/llvm-project/libcxx/include/ext/hash_map contrib/llvm-project/libcxx/include/ext/hash_map index d6ea26c2cf86..a52c6a4066f7 100644 --- contrib/llvm-project/libcxx/include/ext/hash_map +++ contrib/llvm-project/libcxx/include/ext/hash_map @@ -203,10 +203,10 @@ template <class Key, class T, class Hash, class Pred, class Alloc> #include <__config> #include <__hash_table> +#include <ext/__hash> #include <functional> #include <stdexcept> #include <type_traits> -#include <ext/__hash> #if defined(__DEPRECATED) && __DEPRECATED #if defined(_LIBCPP_WARNING) diff --git contrib/llvm-project/libcxx/include/ext/hash_set contrib/llvm-project/libcxx/include/ext/hash_set index 7d19ccd006e2..bca008d172a2 100644 --- contrib/llvm-project/libcxx/include/ext/hash_set +++ contrib/llvm-project/libcxx/include/ext/hash_set @@ -194,8 +194,8 @@ template <class Value, class Hash, class Pred, class Alloc> #include <__config> #include <__hash_table> -#include <functional> #include <ext/__hash> +#include <functional> #if defined(__DEPRECATED) && __DEPRECATED #if defined(_LIBCPP_WARNING) diff --git contrib/llvm-project/libcxx/include/filesystem contrib/llvm-project/libcxx/include/filesystem index 9f5b42747b34..74f596599a1e 100644 --- contrib/llvm-project/libcxx/include/filesystem +++ contrib/llvm-project/libcxx/include/filesystem @@ -248,8 +248,8 @@ inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_direct #include <__filesystem/file_type.h> #include <__filesystem/filesystem_error.h> #include <__filesystem/operations.h> -#include <__filesystem/path_iterator.h> #include <__filesystem/path.h> +#include <__filesystem/path_iterator.h> #include <__filesystem/perm_options.h> #include <__filesystem/perms.h> #include <__filesystem/recursive_directory_iterator.h> diff --git contrib/llvm-project/libcxx/include/format contrib/llvm-project/libcxx/include/format index 788b9c299abc..4cf146ead17a 100644 --- contrib/llvm-project/libcxx/include/format +++ contrib/llvm-project/libcxx/include/format @@ -14,43 +14,15 @@ namespace std { // [format.context], class template basic_format_context - template<class Out, class charT> - class basic_format_context { - basic_format_args<basic_format_context> args_; // exposition only - Out out_; // exposition only - - public: - using iterator = Out; - using char_type = charT; - template<class T> using formatter_type = formatter<T, charT>; - - basic_format_arg<basic_format_context> arg(size_t id) const; - std::locale locale(); - - iterator out(); - void advance_to(iterator it); - }; + template<class Out, class charT> class basic_format_context; using format_context = basic_format_context<unspecified, char>; using wformat_context = basic_format_context<unspecified, wchar_t>; // [format.args], class template basic_format_args - template<class Context> - class basic_format_args { - size_t size_; // exposition only - const basic_format_arg<Context>* data_; // exposition only - - public: - basic_format_args() noexcept; - - template<class... Args> - basic_format_args(const format-arg-store<Context, Args...>& store) noexcept; - - basic_format_arg<Context> get(size_t i) const noexcept; - }; + template<class Context> class basic_format_args; using format_args = basic_format_args<format_context>; using wformat_args = basic_format_args<wformat_context>; - // [format.functions], formatting functions template<class... Args> string format(string_view fmt, const Args&... args); @@ -90,8 +62,7 @@ namespace std { Out out; iter_difference_t<Out> size; }; - - template<class Out, class... Args> + template<class Out, class... Args> format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, string_view fmt, const Args&... args); template<class Out, class... Args> @@ -116,99 +87,22 @@ namespace std { size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args); // [format.formatter], formatter - template<> struct formatter<char, char>; - template<> struct formatter<char, wchar_t>; - template<> struct formatter<wchar_t, wchar_t>; - - template<> struct formatter<charT*, charT>; - template<> struct formatter<const charT*, charT>; - template<size_t N> struct formatter<const charT[N], charT>; - template<class traits, class Allocator> - struct formatter<basic_string<charT, traits, Allocator>, charT>; - template<class traits> - struct formatter<basic_string_view<charT, traits>, charT>; + template<class T, class charT = char> struct formatter; // [format.parse.ctx], class template basic_format_parse_context - template<class charT> - class basic_format_parse_context { - public: - using char_type = charT; - using const_iterator = typename basic_string_view<charT>::const_iterator; - using iterator = const_iterator; - - private: - iterator begin_; // exposition only - iterator end_; // exposition only - enum indexing { unknown, manual, automatic }; // exposition only - indexing indexing_; // exposition only - size_t next_arg_id_; // exposition only - size_t num_args_; // exposition only - - public: - constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, - size_t num_args = 0) noexcept; - basic_format_parse_context(const basic_format_parse_context&) = delete; - basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; - - constexpr const_iterator begin() const noexcept; - constexpr const_iterator end() const noexcept; - constexpr void advance_to(const_iterator it); - - constexpr size_t next_arg_id(); - constexpr void check_arg_id(size_t id); - }; + template<class charT> class basic_format_parse_context; using format_parse_context = basic_format_parse_context<char>; using wformat_parse_context = basic_format_parse_context<wchar_t>; // [format.arguments], arguments // [format.arg], class template basic_format_arg - template<class Context> - class basic_format_arg { - public: - class handle; - - private: - using char_type = typename Context::char_type; // exposition only - - variant<monostate, bool, char_type, - int, unsigned int, long long int, unsigned long long int, - float, double, long double, - const char_type*, basic_string_view<char_type>, - const void*, handle> value; // exposition only - - template<class T> explicit basic_format_arg(const T& v) noexcept; // exposition only - explicit basic_format_arg(float n) noexcept; // exposition only - explicit basic_format_arg(double n) noexcept; // exposition only - explicit basic_format_arg(long double n) noexcept; // exposition only - explicit basic_format_arg(const char_type* s); // exposition only - - template<class traits> - explicit basic_format_arg( - basic_string_view<char_type, traits> s) noexcept; // exposition only - - template<class traits, class Allocator> - explicit basic_format_arg( - const basic_string<char_type, traits, Allocator>& s) noexcept; // exposition only - - explicit basic_format_arg(nullptr_t) noexcept; // exposition only - - template<class T> - explicit basic_format_arg(const T* p) noexcept; // exposition only - - public: - basic_format_arg() noexcept; - - explicit operator bool() const noexcept; - }; + template<class Context> class basic_format_arg; template<class Visitor, class Context> see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg); // [format.arg.store], class template format-arg-store - template<class Context, class... Args> - struct format-arg-store { // exposition only - array<basic_format_arg<Context>, sizeof...(Args)> args; - }; + template<class Context, class... Args> struct format-arg-store; // exposition only template<class Context = format_context, class... Args> format-arg-store<Context, Args...> @@ -218,43 +112,7 @@ namespace std { make_wformat_args(const Args&... args); // [format.error], class format_error - class format_error : public runtime_error { - public: - explicit format_error(const string& what_arg); - explicit format_error(const char* what_arg); - }; - - // [format.parse.ctx], class template basic_format_parse_context - template<class charT> - class basic_format_parse_context { - public: - using char_type = charT; - using const_iterator = typename basic_string_view<charT>::const_iterator; - using iterator = const_iterator; - - private: - iterator begin_; // exposition only - iterator end_; // exposition only - enum indexing { unknown, manual, automatic }; // exposition only - indexing indexing_; // exposition only - size_t next_arg_id_; // exposition only - size_t num_args_; // exposition only - - public: - constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, - size_t num_args = 0) noexcept; - basic_format_parse_context(const basic_format_parse_context&) = delete; - basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; - - constexpr const_iterator begin() const noexcept; - constexpr const_iterator end() const noexcept; - constexpr void advance_to(const_iterator it); - - constexpr size_t next_arg_id(); - constexpr void check_arg_id(size_t id); - }; - using format_parse_context = basic_format_parse_context<char>; - using wformat_parse_context = basic_format_parse_context<wchar_t>; + class format_error; } */ @@ -277,7 +135,9 @@ namespace std { #include <__format/formatter.h> #include <__format/formatter_bool.h> #include <__format/formatter_char.h> +#include <__format/formatter_floating_point.h> #include <__format/formatter_integer.h> +#include <__format/formatter_pointer.h> #include <__format/formatter_string.h> #include <__format/parser_std_format_spec.h> #include <__variant/monostate.h> @@ -367,6 +227,8 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end, [&](auto __arg) { if constexpr (same_as<decltype(__arg), monostate>) __throw_format_error("Argument index out of bounds"); + else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>) + __arg.format(__parse_ctx, __ctx); else { formatter<decltype(__arg), _CharT> __formatter; __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); diff --git contrib/llvm-project/libcxx/include/fstream contrib/llvm-project/libcxx/include/fstream index 3d64adcb23d1..fc0a9204ed60 100644 --- contrib/llvm-project/libcxx/include/fstream +++ contrib/llvm-project/libcxx/include/fstream @@ -187,6 +187,7 @@ typedef basic_fstream<wchar_t> wfstream; #include <cstdlib> #include <istream> #include <ostream> +#include <version> #if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) # include <filesystem> diff --git contrib/llvm-project/libcxx/include/functional contrib/llvm-project/libcxx/include/functional index 53a5f2bc3770..3a24b975881c 100644 --- contrib/llvm-project/libcxx/include/functional +++ contrib/llvm-project/libcxx/include/functional @@ -496,9 +496,9 @@ POLICY: For non-variadic implementations, the number of arguments is limited #include <__debug> #include <__functional/binary_function.h> // TODO: deprecate #include <__functional/binary_negate.h> +#include <__functional/bind.h> #include <__functional/bind_back.h> #include <__functional/bind_front.h> -#include <__functional/bind.h> #include <__functional/binder1st.h> #include <__functional/binder2nd.h> #include <__functional/compose.h> diff --git contrib/llvm-project/libcxx/include/future contrib/llvm-project/libcxx/include/future index 6b666a70f48e..e35eedf35641 100644 --- contrib/llvm-project/libcxx/include/future +++ contrib/llvm-project/libcxx/include/future @@ -374,6 +374,7 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; #include <mutex> #include <system_error> #include <thread> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/ios contrib/llvm-project/libcxx/include/ios index 237d146dfb85..74c3c63bd347 100644 --- contrib/llvm-project/libcxx/include/ios +++ contrib/llvm-project/libcxx/include/ios @@ -214,6 +214,7 @@ storage-class-specifier const error_category& iostream_category() noexcept; #include <__locale> #include <iosfwd> #include <system_error> +#include <version> #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) #include <atomic> // for __xindex_ diff --git contrib/llvm-project/libcxx/include/iosfwd contrib/llvm-project/libcxx/include/iosfwd index 938d712cf36b..c2ba8ee9e652 100644 --- contrib/llvm-project/libcxx/include/iosfwd +++ contrib/llvm-project/libcxx/include/iosfwd @@ -96,6 +96,7 @@ using u32streampos = fpos<char_traits<char32_t>::state_type>; #include <__config> #include <__mbstate_t.h> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/iostream contrib/llvm-project/libcxx/include/iostream index 7397acfc678b..793f08ab1330 100644 --- contrib/llvm-project/libcxx/include/iostream +++ contrib/llvm-project/libcxx/include/iostream @@ -38,6 +38,7 @@ extern wostream wclog; #include <istream> #include <ostream> #include <streambuf> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/iterator contrib/llvm-project/libcxx/include/iterator index 4dd9902d79a2..29097a9aa8bf 100644 --- contrib/llvm-project/libcxx/include/iterator +++ contrib/llvm-project/libcxx/include/iterator @@ -140,6 +140,11 @@ template<class In, class Out> template<class I1, class I2 = I1> concept indirectly_swappable = see below; // since C++20 +template<class I1, class I2, class R, class P1 = identity, + class P2 = identity> + concept indirectly_comparable = + indirect_binary_predicate<R, projected<I1, P1>, projected<I2, P2>>; // since C++20 + template<input_or_output_iterator I, sentinel_for<I> S> requires (!same_as<I, S> && copyable<I>) class common_iterator; // since C++20 @@ -593,17 +598,18 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept; #include <__iterator/erase_if_container.h> #include <__iterator/front_insert_iterator.h> #include <__iterator/incrementable_traits.h> +#include <__iterator/indirectly_comparable.h> #include <__iterator/insert_iterator.h> -#include <__iterator/istreambuf_iterator.h> #include <__iterator/istream_iterator.h> -#include <__iterator/iterator.h> -#include <__iterator/iterator_traits.h> +#include <__iterator/istreambuf_iterator.h> #include <__iterator/iter_move.h> #include <__iterator/iter_swap.h> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> #include <__iterator/move_iterator.h> #include <__iterator/next.h> -#include <__iterator/ostreambuf_iterator.h> #include <__iterator/ostream_iterator.h> +#include <__iterator/ostreambuf_iterator.h> #include <__iterator/prev.h> #include <__iterator/projected.h> #include <__iterator/readable_traits.h> diff --git contrib/llvm-project/libcxx/include/latch contrib/llvm-project/libcxx/include/latch index e65825991b59..2cc9222baadc 100644 --- contrib/llvm-project/libcxx/include/latch +++ contrib/llvm-project/libcxx/include/latch @@ -43,6 +43,7 @@ namespace std #include <__availability> #include <__config> #include <atomic> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/list contrib/llvm-project/libcxx/include/list index c9c050a4f1f0..258fe2cee727 100644 --- contrib/llvm-project/libcxx/include/list +++ contrib/llvm-project/libcxx/include/list @@ -319,9 +319,7 @@ public: _LIBCPP_INLINE_VISIBILITY __list_iterator() _NOEXCEPT : __ptr_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } #if _LIBCPP_DEBUG_LEVEL == 2 @@ -355,29 +353,23 @@ public: _LIBCPP_INLINE_VISIBILITY reference operator*() const { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::iterator"); return __ptr_->__as_node()->__value_; } _LIBCPP_INLINE_VISIBILITY pointer operator->() const { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::iterator"); return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_); } _LIBCPP_INLINE_VISIBILITY __list_iterator& operator++() { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable list::iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable list::iterator"); __ptr_ = __ptr_->__next_; return *this; } @@ -387,10 +379,8 @@ public: _LIBCPP_INLINE_VISIBILITY __list_iterator& operator--() { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), - "Attempted to decrement a non-decrementable list::iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement a non-decrementable list::iterator"); __ptr_ = __ptr_->__prev_; return *this; } @@ -439,9 +429,7 @@ public: _LIBCPP_INLINE_VISIBILITY __list_const_iterator() _NOEXCEPT : __ptr_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } _LIBCPP_INLINE_VISIBILITY __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT @@ -482,29 +470,23 @@ public: _LIBCPP_INLINE_VISIBILITY reference operator*() const { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::const_iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::const_iterator"); return __ptr_->__as_node()->__value_; } _LIBCPP_INLINE_VISIBILITY pointer operator->() const { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable list::const_iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::const_iterator"); return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_); } _LIBCPP_INLINE_VISIBILITY __list_const_iterator& operator++() { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable list::const_iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable list::const_iterator"); __ptr_ = __ptr_->__next_; return *this; } @@ -514,10 +496,8 @@ public: _LIBCPP_INLINE_VISIBILITY __list_const_iterator& operator--() { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), - "Attempted to decrement a non-decrementable list::const_iterator"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement a non-decrementable list::const_iterator"); __ptr_ = __ptr_->__prev_; return *this; } @@ -869,16 +849,12 @@ public: list() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } _LIBCPP_INLINE_VISIBILITY explicit list(const allocator_type& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } explicit list(size_type __n); #if _LIBCPP_STD_VER > 11 @@ -888,9 +864,7 @@ public: template <class = __enable_if_t<__is_allocator<_Alloc>::value> > list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __n > 0; --__n) push_back(__x); } @@ -1217,9 +1191,7 @@ list<_Tp, _Alloc>::__iterator(size_type __n) template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(size_type __n) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __n > 0; --__n) #ifndef _LIBCPP_CXX03_LANG emplace_back(); @@ -1232,9 +1204,7 @@ list<_Tp, _Alloc>::list(size_type __n) template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __n > 0; --__n) emplace_back(); } @@ -1243,9 +1213,7 @@ list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a) template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __n > 0; --__n) push_back(__x); } @@ -1255,9 +1223,7 @@ template <class _InpIter> list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __f != __l; ++__f) __emplace_back(*__f); } @@ -1268,9 +1234,7 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a, typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __f != __l; ++__f) __emplace_back(*__f); } @@ -1279,9 +1243,7 @@ template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(const list& __c) : base(__node_alloc_traits::select_on_container_copy_construction( __c.__node_alloc())) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) push_back(*__i); } @@ -1290,9 +1252,7 @@ template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(const list& __c, const __identity_t<allocator_type>& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) push_back(*__i); } @@ -1303,9 +1263,7 @@ template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), __e = __il.end(); __i != __e; ++__i) push_back(*__i); @@ -1314,9 +1272,7 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), __e = __il.end(); __i != __e; ++__i) push_back(*__i); @@ -1324,11 +1280,9 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il) template <class _Tp, class _Alloc> inline list<_Tp, _Alloc>::list(list&& __c) - _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) - : base(_VSTD::move(__c.__node_alloc())) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) + : base(_VSTD::move(__c.__node_alloc())) { + _VSTD::__debug_db_insert_c(this); splice(end(), __c); } @@ -1337,9 +1291,7 @@ inline list<_Tp, _Alloc>::list(list&& __c, const __identity_t<allocator_type>& __a) : base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a == __c.get_allocator()) splice(end(), __c); else @@ -1448,11 +1400,8 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, x) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::insert(iterator, x) called with an iterator not referring to this list"); __node_allocator& __na = base::__node_alloc(); __hold_pointer __hold = __allocate_node(__na); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); @@ -1469,10 +1418,9 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x) { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::insert(iterator, n, x) called with an iterator not referring to this list"); #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, n, x) called with an iterator not" - " referring to this list"); iterator __r(__p.__ptr_, this); #else iterator __r(__p.__ptr_); @@ -1535,10 +1483,9 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::insert(iterator, range) called with an iterator not referring to this list"); #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, range) called with an iterator not" - " referring to this list"); iterator __r(__p.__ptr_, this); #else iterator __r(__p.__ptr_); @@ -1694,11 +1641,8 @@ template <class... _Args> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::emplace(iterator, args...) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::emplace(iterator, args...) called with an iterator not referring to this list"); __node_allocator& __na = base::__node_alloc(); __hold_pointer __hold = __allocate_node(__na); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); @@ -1717,11 +1661,8 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::insert(iterator, x) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::insert(iterator, x) called with an iterator not referring to this list"); __node_allocator& __na = base::__node_alloc(); __hold_pointer __hold = __allocate_node(__na); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); @@ -1800,11 +1741,8 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __p) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::erase(iterator) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::erase(iterator) called with an iterator not referring to this list"); _LIBCPP_ASSERT(__p != end(), "list::erase(iterator) called with a non-dereferenceable iterator"); __node_allocator& __na = base::__node_alloc(); @@ -1841,14 +1779,10 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == this, - "list::erase(iterator, iterator) called with an iterator not" - " referring to this list"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == this, - "list::erase(iterator, iterator) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == this, + "list::erase(iterator, iterator) called with an iterator not referring to this list"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == this, + "list::erase(iterator, iterator) called with an iterator not referring to this list"); if (__f != __l) { __node_allocator& __na = base::__node_alloc(); @@ -2006,11 +1940,8 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) { _LIBCPP_ASSERT(this != _VSTD::addressof(__c), "list::splice(iterator, list) called with this == &list"); -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::splice(iterator, list) called with an iterator not" - " referring to this list"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::splice(iterator, list) called with an iterator not referring to this list"); if (!__c.empty()) { __link_pointer __f = __c.__end_.__next_; @@ -2046,17 +1977,13 @@ template <class _Tp, class _Alloc> void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::splice(iterator, list, iterator) called with the first iterator" - " not referring to this list"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__i)) == _VSTD::addressof(__c), - "list::splice(iterator, list, iterator) called with the second iterator" - " not referring to the list argument"); - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(_VSTD::addressof(__i)), - "list::splice(iterator, list, iterator) called with the second iterator" - " not dereferenceable"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::splice(iterator, list, iterator) called with the first iterator not referring to this list"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__i)) == _VSTD::addressof(__c), + "list::splice(iterator, list, iterator) called with the second iterator not referring to the list argument"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(_VSTD::addressof(__i)), + "list::splice(iterator, list, iterator) called with the second iterator not dereferenceable"); + if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_) { __link_pointer __f = __i.__ptr_; @@ -2091,23 +2018,20 @@ template <class _Tp, class _Alloc> void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l) { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "list::splice(iterator, list, iterator, iterator) called with first iterator not referring to this list"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == _VSTD::addressof(__c), + "list::splice(iterator, list, iterator, iterator) called with second iterator not referring to the list argument"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c), + "list::splice(iterator, list, iterator, iterator) called with third iterator not referring to the list argument"); + #if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "list::splice(iterator, list, iterator, iterator) called with first iterator not" - " referring to this list"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == _VSTD::addressof(__c), - "list::splice(iterator, list, iterator, iterator) called with second iterator not" - " referring to the list argument"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c), - "list::splice(iterator, list, iterator, iterator) called with third iterator not" - " referring to the list argument"); if (this == _VSTD::addressof(__c)) { for (const_iterator __i = __f; __i != __l; ++__i) - _LIBCPP_ASSERT(__i != __p, - "list::splice(iterator, list, iterator, iterator)" - " called with the first iterator within the range" - " of the second and third iterators"); + _LIBCPP_DEBUG_ASSERT(__i != __p, + "list::splice(iterator, list, iterator, iterator)" + " called with the first iterator within the range of the second and third iterators"); } #endif if (__f != __l) diff --git contrib/llvm-project/libcxx/include/locale contrib/llvm-project/libcxx/include/locale index 86af26c3e35e..7c2d2361f751 100644 --- contrib/llvm-project/libcxx/include/locale +++ contrib/llvm-project/libcxx/include/locale @@ -416,11 +416,11 @@ struct __num_get unsigned& __dc, _CharT __thousands_sep, const string& __grouping, unsigned* __g, unsigned*& __g_end, const _CharT* __atoms); private: - template<typename T> - const T* __do_widen_p(ios_base& __iob, T* __atoms) const + template<typename _Tp> + const _Tp* __do_widen_p(ios_base& __iob, _Tp* __atoms) const { locale __loc = __iob.getloc(); - use_facet<ctype<T> >(__loc).widen(__src, __src + 26, __atoms); + use_facet<ctype<_Tp> >(__loc).widen(__src, __src + 26, __atoms); return __atoms; } diff --git contrib/llvm-project/libcxx/include/math.h contrib/llvm-project/libcxx/include/math.h index 850cdcfb32f6..e59ac6be11bf 100644 --- contrib/llvm-project/libcxx/include/math.h +++ contrib/llvm-project/libcxx/include/math.h @@ -305,9 +305,9 @@ long double truncl(long double x); // back to C++ linkage before including these C++ headers. extern "C++" { +#include <limits> #include <stdlib.h> #include <type_traits> -#include <limits> // signbit diff --git contrib/llvm-project/libcxx/include/memory contrib/llvm-project/libcxx/include/memory index 3ed1530f2a75..db59936707e4 100644 --- contrib/llvm-project/libcxx/include/memory +++ contrib/llvm-project/libcxx/include/memory @@ -181,82 +181,189 @@ template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); +namespace ranges { + +template<class InputIterator, class OutputIterator> +using uninitialized_copy_result = in_out_result<InputIterator, OutputIterator>; // since C++20 + +template<input_iterator InputIterator, sentinel-for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel2> + requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>> +uninitialized_copy_result<InputIterator, OutputIterator> +uninitialized_copy(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20 + +template<input_range InputRange, nothrow-forward-range OutputRange> + requires constructible_from<range_value_t<OutputRange>, range_reference_t<InputRange>> +uninitialized_copy_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>> +uninitialized_copy(InputRange&& in_range, OutputRange&& out_range); // since C++20 + +} + template <class InputIterator, class Size, class ForwardIterator> ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); +namespace ranges { + +template<class InputIterator, class OutputIterator> +using uninitialized_copy_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20 + +template<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel> + requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>> +uninitialized_copy_n_result<InputIterator, OutputIterator> +uninitialized_copy_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20 + +} + template <class ForwardIterator, class T> void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel, class T> requires constructible_from<iter_value_t<ForwardIterator>, const T&> -ForwardIterator ranges::uninitialized_fill(ForwardIterator first, Sentinel last, const T& x); // since C++20 +ForwardIterator uninitialized_fill(ForwardIterator first, Sentinel last, const T& x); // since C++20 template <nothrow-forward-range ForwardRange, class T> requires constructible_from<range_value_t<ForwardRange>, const T&> -borrowed_iterator_t<ForwardRange> ranges::uninitialized_fill(ForwardRange&& range, const T& x); // since C++20 +borrowed_iterator_t<ForwardRange> uninitialized_fill(ForwardRange&& range, const T& x); // since C++20 + +} template <class ForwardIterator, class Size, class T> ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator, class T> requires constructible_from<iter_value_t<ForwardIterator>, const T&> -ForwardIterator ranges::uninitialized_fill_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 +ForwardIterator uninitialized_fill_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 + +} template <class T, class ...Args> constexpr T* construct_at(T* location, Args&& ...args); // since C++20 +namespace ranges { + template<class T, class... Args> + constexpr T* construct_at(T* location, Args&&... args); // since C++20 +} + template <class T> void destroy_at(T* location); // constexpr in C++20 +namespace ranges { + template<destructible T> + constexpr void destroy_at(T* location) noexcept; // since C++20 +} + template <class ForwardIterator> void destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20 +namespace ranges { + template<nothrow-input-iterator InputIterator, nothrow-sentinel-for<InputIterator> Sentinel> + requires destructible<iter_value_t<InputIterator>> + constexpr InputIterator destroy(InputIterator first, Sentinel last) noexcept; // since C++20 + template<nothrow-input-range InputRange> + requires destructible<range_value_t<InputRange>> + constexpr borrowed_iterator_t<InputRange> destroy(InputRange&& range) noexcept; // since C++20 +} + template <class ForwardIterator, class Size> ForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20 +namespace ranges { + template<nothrow-input-iterator InputIterator> + requires destructible<iter_value_t<InputIterator>> + constexpr InputIterator destroy_n(InputIterator first, iter_difference_t<InputIterator> n) noexcept; // since C++20 +} + template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); +namespace ranges { + +template<class InputIterator, class OutputIterator> +using uninitialized_move_result = in_out_result<InputIterator, OutputIterator>; // since C++20 + +template <input_iterator InputIterator, sentinel_for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<O> Sentinel2> + requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>> +uninitialized_move_result<InputIterator, OutputIterator> +uninitialized_move(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20 + +template<input_range InputRange, nothrow-forward-range OutputRange> + requires constructible_from<range_value_t<OutputRange>, range_rvalue_reference_t<InputRange>> +uninitialized_move_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>> +uninitialized_move(InputRange&& in_range, OutputRange&& out_range); // since C++20 + +} + template <class InputIterator, class Size, class ForwardIterator> pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); +namespace ranges { + +template<class InputIterator, class OutputIterator> +using uninitialized_move_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20 + +template<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel> + requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>> +uninitialized_move_n_result<InputIterator, OutputIterator> +uninitialized_move_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20 + +} + template <class ForwardIterator> void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel> requires default_initializable<iter_value_t<ForwardIterator>> - ForwardIterator ranges::uninitialized_value_construct(ForwardIterator first, Sentinel last); // since C++20 + ForwardIterator uninitialized_value_construct(ForwardIterator first, Sentinel last); // since C++20 template <nothrow-forward-range ForwardRange> requires default_initializable<range_value_t<ForwardRange>> - borrowed_iterator_t<ForwardRange> ranges::uninitialized_value_construct(ForwardRange&& r); // since C++20 + borrowed_iterator_t<ForwardRange> uninitialized_value_construct(ForwardRange&& r); // since C++20 + +} template <class ForwardIterator, class Size> ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator> requires default_initializable<iter_value_t<ForwardIterator>> - ForwardIterator ranges::uninitialized_value_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 + ForwardIterator uninitialized_value_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 + +} template <class ForwardIterator> void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel> requires default_initializable<iter_value_t<ForwardIterator>> - ForwardIterator ranges::uninitialized_default_construct(ForwardIterator first, Sentinel last); // since C++20 + ForwardIterator uninitialized_default_construct(ForwardIterator first, Sentinel last); // since C++20 template <nothrow-forward-range ForwardRange> requires default_initializable<range_value_t<ForwardRange>> - borrowed_iterator_t<ForwardRange> ranges::uninitialized_default_construct(ForwardRange&& r); // since C++20 + borrowed_iterator_t<ForwardRange> uninitialized_default_construct(ForwardRange&& r); // since C++20 + +} template <class ForwardIterator, class Size> ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); +namespace ranges { + template <nothrow-forward-iterator ForwardIterator> requires default_initializable<iter_value_t<ForwardIterator>> - ForwardIterator ranges::uninitialized_default_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 + ForwardIterator uninitialized_default_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 + +} template <class Y> struct auto_ptr_ref {}; // deprecated in C++11, removed in C++17 @@ -708,6 +815,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); #include <__memory/concepts.h> #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> +#include <__memory/ranges_construct_at.h> #include <__memory/ranges_uninitialized_algorithms.h> #include <__memory/raw_storage_iterator.h> #include <__memory/shared_ptr.h> diff --git contrib/llvm-project/libcxx/include/module.modulemap contrib/llvm-project/libcxx/include/module.modulemap index 1dc6db406a74..90fae9bb8362 100644 --- contrib/llvm-project/libcxx/include/module.modulemap +++ contrib/llvm-project/libcxx/include/module.modulemap @@ -246,6 +246,8 @@ module std [system] { module generate { private header "__algorithm/generate.h" } module generate_n { private header "__algorithm/generate_n.h" } module half_positive { private header "__algorithm/half_positive.h" } + module in_in_result { private header "__algorithm/in_in_result.h" } + module in_out_result { private header "__algorithm/in_out_result.h" } module includes { private header "__algorithm/includes.h" } module inplace_merge { private header "__algorithm/inplace_merge.h" } module is_heap { private header "__algorithm/is_heap.h" } @@ -362,6 +364,17 @@ module std [system] { module chrono { header "chrono" export * + + module __chrono { + module calendar { private header "__chrono/calendar.h" } + module convert_to_timespec { private header "__chrono/convert_to_timespec.h" } + module duration { private header "__chrono/duration.h" } + module file_clock { private header "__chrono/file_clock.h" } + module high_resolution_clock { private header "__chrono/high_resolution_clock.h" } + module steady_clock { private header "__chrono/steady_clock.h" } + module system_clock { private header "__chrono/system_clock.h" } + module time_point { private header "__chrono/time_point.h" } + } } module codecvt { header "codecvt" @@ -430,8 +443,8 @@ module std [system] { module __coroutine { module coroutine_handle { private header "__coroutine/coroutine_handle.h" } module coroutine_traits { private header "__coroutine/coroutine_traits.h" } - module trivial_awaitables { private header "__coroutine/trivial_awaitables.h" } module noop_coroutine_handle { private header "__coroutine/noop_coroutine_handle.h" } + module trivial_awaitables { private header "__coroutine/trivial_awaitables.h" } } } module deque { @@ -461,8 +474,8 @@ module std [system] { module file_type { private header "__filesystem/file_type.h" } module filesystem_error { private header "__filesystem/filesystem_error.h" } module operations { private header "__filesystem/operations.h" } - module path_iterator { private header "__filesystem/path_iterator.h" } module path { private header "__filesystem/path.h" } + module path_iterator { private header "__filesystem/path_iterator.h" } module perm_options { private header "__filesystem/perm_options.h" } module perms { private header "__filesystem/perms.h" } module recursive_directory_iterator { private header "__filesystem/recursive_directory_iterator.h" } @@ -475,25 +488,27 @@ module std [system] { export * module __format { - module format_arg { private header "__format/format_arg.h" } - module format_args { private header "__format/format_args.h" } + module format_arg { private header "__format/format_arg.h" } + module format_args { private header "__format/format_args.h" } module format_context { private header "__format/format_context.h" export optional export locale } - module format_error { private header "__format/format_error.h" } - module format_fwd { private header "__format/format_fwd.h" } - module format_parse_context { private header "__format/format_parse_context.h" } - module format_string { private header "__format/format_string.h" } - module format_to_n_result { private header "__format/format_to_n_result.h" } - module formatter { private header "__format/formatter.h" } - module formatter_bool { private header "__format/formatter_bool.h" } - module formatter_char { private header "__format/formatter_char.h" } - module formatter_integer { private header "__format/formatter_integer.h" } - module formatter_integral { private header "__format/formatter_integral.h" } - module formatter_string { private header "__format/formatter_string.h" } - module parser_std_format_spec { private header "__format/parser_std_format_spec.h" } + module format_error { private header "__format/format_error.h" } + module format_fwd { private header "__format/format_fwd.h" } + module format_parse_context { private header "__format/format_parse_context.h" } + module format_string { private header "__format/format_string.h" } + module format_to_n_result { private header "__format/format_to_n_result.h" } + module formatter { private header "__format/formatter.h" } + module formatter_bool { private header "__format/formatter_bool.h" } + module formatter_char { private header "__format/formatter_char.h" } + module formatter_floating_point { private header "__format/formatter_floating_point.h" } + module formatter_integer { private header "__format/formatter_integer.h" } + module formatter_integral { private header "__format/formatter_integral.h" } + module formatter_pointer { private header "__format/formatter_pointer.h" } + module formatter_string { private header "__format/formatter_string.h" } + module parser_std_format_spec { private header "__format/parser_std_format_spec.h" } } } module forward_list { @@ -579,10 +594,7 @@ module std [system] { module __iterator { module access { private header "__iterator/access.h" } - module advance { - private header "__iterator/advance.h" - export __function_like - } + module advance { private header "__iterator/advance.h" } module back_insert_iterator { private header "__iterator/back_insert_iterator.h" } module common_iterator { private header "__iterator/common_iterator.h" } module concepts { private header "__iterator/concepts.h" } @@ -594,6 +606,7 @@ module std [system] { module erase_if_container { private header "__iterator/erase_if_container.h" } module front_insert_iterator { private header "__iterator/front_insert_iterator.h" } module incrementable_traits { private header "__iterator/incrementable_traits.h" } + module indirectly_comparable { private header "__iterator/indirectly_comparable.h" } module insert_iterator { private header "__iterator/insert_iterator.h" } module istream_iterator { private header "__iterator/istream_iterator.h" } module istreambuf_iterator { private header "__iterator/istreambuf_iterator.h" } @@ -602,16 +615,10 @@ module std [system] { module iterator { private header "__iterator/iterator.h" } module iterator_traits { private header "__iterator/iterator_traits.h" } module move_iterator { private header "__iterator/move_iterator.h" } - module next { - private header "__iterator/next.h" - export __function_like - } + module next { private header "__iterator/next.h" } module ostream_iterator { private header "__iterator/ostream_iterator.h" } module ostreambuf_iterator { private header "__iterator/ostreambuf_iterator.h" } - module prev { - private header "__iterator/prev.h" - export __function_like - } + module prev { private header "__iterator/prev.h" } module projected { private header "__iterator/projected.h" } module readable_traits { private header "__iterator/readable_traits.h" } module reverse_access { private header "__iterator/reverse_access.h" } @@ -659,10 +666,8 @@ module std [system] { module concepts { private header "__memory/concepts.h" } module construct_at { private header "__memory/construct_at.h" } module pointer_traits { private header "__memory/pointer_traits.h" } - module ranges_uninitialized_algorithms { - private header "__memory/ranges_uninitialized_algorithms.h" - export __function_like - } + module ranges_construct_at { private header "__memory/ranges_construct_at.h" } + module ranges_uninitialized_algorithms { private header "__memory/ranges_uninitialized_algorithms.h" } module raw_storage_iterator { private header "__memory/raw_storage_iterator.h" } module shared_ptr { private header "__memory/shared_ptr.h" } module temporary_buffer { private header "__memory/temporary_buffer.h" } @@ -793,11 +798,12 @@ module std [system] { module iota_view { private header "__ranges/iota_view.h" } module join_view { private header "__ranges/join_view.h" } module non_propagating_cache { private header "__ranges/non_propagating_cache.h" } + module owning_view { private header "__ranges/owning_view.h" } module range_adaptor { private header "__ranges/range_adaptor.h" } module ref_view { private header "__ranges/ref_view.h" } module reverse_view { private header "__ranges/reverse_view.h" } - module size { private header "__ranges/size.h" } module single_view { private header "__ranges/single_view.h" } + module size { private header "__ranges/size.h" } module subrange { private header "__ranges/subrange.h" } module take_view { private header "__ranges/take_view.h" } module transform_view { @@ -884,7 +890,8 @@ module std [system] { export * module __thread { - module poll_with_backoff { private header "__thread/poll_with_backoff.h" } + module poll_with_backoff { private header "__thread/poll_with_backoff.h" } + module timed_backoff_policy { private header "__thread/timed_backoff_policy.h" } } } module tuple { @@ -968,10 +975,9 @@ module std [system] { module __bits { private header "__bits" export * } module __debug { header "__debug" export * } module __errc { private header "__errc" export * } - module __function_like { private header "__function_like.h" export * } module __hash_table { header "__hash_table" export * } module __locale { private header "__locale" export * } - module __mbstate { private header "__mbstate_t.h" export * } + module __mbstate_t { private header "__mbstate_t.h" export * } module __mutex_base { private header "__mutex_base" export * } module __node_handle { private header "__node_handle" export * } module __nullptr { header "__nullptr" export * } diff --git contrib/llvm-project/libcxx/include/numbers contrib/llvm-project/libcxx/include/numbers index ede4e33c7a88..2ac36695b888 100644 --- contrib/llvm-project/libcxx/include/numbers +++ contrib/llvm-project/libcxx/include/numbers @@ -73,42 +73,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace numbers { -template <class T> +template <class _Tp> inline constexpr bool __false = false; -template <class T> +template <class _Tp> struct __illformed { - static_assert(__false<T>, "A program that instantiates a primary template of a mathematical constant variable template is ill-formed."); + static_assert(__false<_Tp>, "A program that instantiates a primary template of a mathematical constant variable template is ill-formed."); }; -template <class T> inline constexpr T e_v = __illformed<T>{}; -template <class T> inline constexpr T log2e_v = __illformed<T>{}; -template <class T> inline constexpr T log10e_v = __illformed<T>{}; -template <class T> inline constexpr T pi_v = __illformed<T>{}; -template <class T> inline constexpr T inv_pi_v = __illformed<T>{}; -template <class T> inline constexpr T inv_sqrtpi_v = __illformed<T>{}; -template <class T> inline constexpr T ln2_v = __illformed<T>{}; -template <class T> inline constexpr T ln10_v = __illformed<T>{}; -template <class T> inline constexpr T sqrt2_v = __illformed<T>{}; -template <class T> inline constexpr T sqrt3_v = __illformed<T>{}; -template <class T> inline constexpr T inv_sqrt3_v = __illformed<T>{}; -template <class T> inline constexpr T egamma_v = __illformed<T>{}; -template <class T> inline constexpr T phi_v = __illformed<T>{}; - -template <floating_point T> inline constexpr T e_v<T> = 2.718281828459045235360287471352662; -template <floating_point T> inline constexpr T log2e_v<T> = 1.442695040888963407359924681001892; -template <floating_point T> inline constexpr T log10e_v<T> = 0.434294481903251827651128918916605; -template <floating_point T> inline constexpr T pi_v<T> = 3.141592653589793238462643383279502; -template <floating_point T> inline constexpr T inv_pi_v<T> = 0.318309886183790671537767526745028; -template <floating_point T> inline constexpr T inv_sqrtpi_v<T> = 0.564189583547756286948079451560772; -template <floating_point T> inline constexpr T ln2_v<T> = 0.693147180559945309417232121458176; -template <floating_point T> inline constexpr T ln10_v<T> = 2.302585092994045684017991454684364; -template <floating_point T> inline constexpr T sqrt2_v<T> = 1.414213562373095048801688724209698; -template <floating_point T> inline constexpr T sqrt3_v<T> = 1.732050807568877293527446341505872; -template <floating_point T> inline constexpr T inv_sqrt3_v<T> = 0.577350269189625764509148780501957; -template <floating_point T> inline constexpr T egamma_v<T> = 0.577215664901532860606512090082402; -template <floating_point T> inline constexpr T phi_v<T> = 1.618033988749894848204586834365638; +template <class _Tp> inline constexpr _Tp e_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp log2e_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp log10e_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp pi_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp inv_pi_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp inv_sqrtpi_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp ln2_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp ln10_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp sqrt2_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp sqrt3_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp inv_sqrt3_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp egamma_v = __illformed<_Tp>{}; +template <class _Tp> inline constexpr _Tp phi_v = __illformed<_Tp>{}; + +template <floating_point _Tp> inline constexpr _Tp e_v<_Tp> = 2.718281828459045235360287471352662; +template <floating_point _Tp> inline constexpr _Tp log2e_v<_Tp> = 1.442695040888963407359924681001892; +template <floating_point _Tp> inline constexpr _Tp log10e_v<_Tp> = 0.434294481903251827651128918916605; +template <floating_point _Tp> inline constexpr _Tp pi_v<_Tp> = 3.141592653589793238462643383279502; +template <floating_point _Tp> inline constexpr _Tp inv_pi_v<_Tp> = 0.318309886183790671537767526745028; +template <floating_point _Tp> inline constexpr _Tp inv_sqrtpi_v<_Tp> = 0.564189583547756286948079451560772; +template <floating_point _Tp> inline constexpr _Tp ln2_v<_Tp> = 0.693147180559945309417232121458176; +template <floating_point _Tp> inline constexpr _Tp ln10_v<_Tp> = 2.302585092994045684017991454684364; +template <floating_point _Tp> inline constexpr _Tp sqrt2_v<_Tp> = 1.414213562373095048801688724209698; +template <floating_point _Tp> inline constexpr _Tp sqrt3_v<_Tp> = 1.732050807568877293527446341505872; +template <floating_point _Tp> inline constexpr _Tp inv_sqrt3_v<_Tp> = 0.577350269189625764509148780501957; +template <floating_point _Tp> inline constexpr _Tp egamma_v<_Tp> = 0.577215664901532860606512090082402; +template <floating_point _Tp> inline constexpr _Tp phi_v<_Tp> = 1.618033988749894848204586834365638; inline constexpr double e = e_v<double>; inline constexpr double log2e = log2e_v<double>; diff --git contrib/llvm-project/libcxx/include/optional contrib/llvm-project/libcxx/include/optional index 63753d9f9f03..917e9b5cdb57 100644 --- contrib/llvm-project/libcxx/include/optional +++ contrib/llvm-project/libcxx/include/optional @@ -1167,8 +1167,8 @@ public: }; #if _LIBCPP_STD_VER >= 17 -template<class T> - optional(T) -> optional<T>; +template<class _Tp> + optional(_Tp) -> optional<_Tp>; #endif // Comparisons between optionals diff --git contrib/llvm-project/libcxx/include/queue contrib/llvm-project/libcxx/include/queue index 03081eb844ba..9e1257b25e0e 100644 --- contrib/llvm-project/libcxx/include/queue +++ contrib/llvm-project/libcxx/include/queue @@ -41,6 +41,8 @@ public: explicit queue(const container_type& c); explicit queue(container_type&& c) + template<class InputIterator> + queue(InputIterator first, InputIterator last); // since C++23 template <class Alloc> explicit queue(const Alloc& a); template <class Alloc> @@ -51,6 +53,8 @@ public: queue(const queue& q, const Alloc& a); template <class Alloc> queue(queue&& q, const Alloc& a); + template <class InputIterator, class Alloc> + queue(InputIterator first, InputIterator last, const Alloc&); // since C++23 bool empty() const; size_type size() const; @@ -71,9 +75,17 @@ public: template<class Container> queue(Container) -> queue<typename Container::value_type, Container>; // C++17 +template<class InputIterator> + queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>; // since C++23 + template<class Container, class Allocator> queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17 +template<class InputIterator, class Allocator> + queue(InputIterator, InputIterator, Allocator) + -> queue<iter-value-type<InputIterator>, + deque<iter-value-type<InputIterator>, Allocator>>; // since C++23 + template <class T, class Container> bool operator==(const queue<T, Container>& x,const queue<T, Container>& y); @@ -206,13 +218,16 @@ template <class T, class Container, class Compare> */ #include <__config> +#include <__iterator/iterator_traits.h> #include <__memory/uses_allocator.h> #include <__utility/forward.h> #include <algorithm> #include <compare> #include <deque> #include <functional> +#include <type_traits> #include <vector> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -255,6 +270,20 @@ public: _LIBCPP_INLINE_VISIBILITY queue(const queue& __q) : c(__q.c) {} +#if _LIBCPP_STD_VER > 20 + template <class _InputIterator, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> + _LIBCPP_HIDE_FROM_ABI + queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) {} + + template <class _InputIterator, + class _Alloc, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>> + _LIBCPP_HIDE_FROM_ABI + queue(_InputIterator __first, _InputIterator __second, const _Alloc& __alloc) : c(__first, __second, __alloc) {} +#endif + _LIBCPP_INLINE_VISIBILITY queue& operator=(const queue& __q) {c = __q.c; return *this;} @@ -358,7 +387,7 @@ public: operator< (const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y); }; -#if _LIBCPP_STD_VER >= 17 +#if _LIBCPP_STD_VER > 14 template<class _Container, class = enable_if_t<!__is_allocator<_Container>::value> > @@ -374,6 +403,20 @@ queue(_Container, _Alloc) -> queue<typename _Container::value_type, _Container>; #endif +#if _LIBCPP_STD_VER > 20 +template <class _InputIterator, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> +queue(_InputIterator, _InputIterator) + -> queue<__iter_value_type<_InputIterator>>; + +template <class _InputIterator, + class _Alloc, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = __enable_if_t<__is_allocator<_Alloc>::value>> +queue(_InputIterator, _InputIterator, _Alloc) + -> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>; +#endif + template <class _Tp, class _Container> inline _LIBCPP_INLINE_VISIBILITY bool diff --git contrib/llvm-project/libcxx/include/random contrib/llvm-project/libcxx/include/random index c88bfce03b19..2e271cec46ad 100644 --- contrib/llvm-project/libcxx/include/random +++ contrib/llvm-project/libcxx/include/random @@ -1715,6 +1715,7 @@ class piecewise_linear_distribution #include <__random/uniform_real_distribution.h> #include <__random/weibull_distribution.h> #include <initializer_list> +#include <version> #include <algorithm> // for backward compatibility; TODO remove it #include <cmath> // for backward compatibility; TODO remove it diff --git contrib/llvm-project/libcxx/include/ranges contrib/llvm-project/libcxx/include/ranges index dd7decf66fa8..eb4492376c5c 100644 --- contrib/llvm-project/libcxx/include/ranges +++ contrib/llvm-project/libcxx/include/ranges @@ -135,6 +135,13 @@ namespace std::ranges { template<class T> inline constexpr bool enable_borrowed_range<ref_view<T>> = true; + template<range R> + requires see below + class owning_view; + + template<class T> + inline constexpr bool enable_borrowed_range<owning_view<T>> = enable_borrowed_range<T>; + // [range.drop], drop view template<view V> class drop_view; @@ -207,8 +214,8 @@ namespace std::ranges { #include <__ranges/dangling.h> #include <__ranges/data.h> #include <__ranges/drop_view.h> -#include <__ranges/empty_view.h> #include <__ranges/empty.h> +#include <__ranges/empty_view.h> #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> #include <__ranges/iota_view.h> diff --git contrib/llvm-project/libcxx/include/ratio contrib/llvm-project/libcxx/include/ratio index 16b45a28ed8b..8859261208d0 100644 --- contrib/llvm-project/libcxx/include/ratio +++ contrib/llvm-project/libcxx/include/ratio @@ -81,6 +81,7 @@ typedef ratio<1000000000000000000000000, 1> yotta; // not supported #include <climits> #include <cstdint> #include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/regex contrib/llvm-project/libcxx/include/regex index 8203c81659c8..59b2c9a23399 100644 --- contrib/llvm-project/libcxx/include/regex +++ contrib/llvm-project/libcxx/include/regex @@ -1310,19 +1310,51 @@ regex_traits<_CharT>::isctype(char_type __c, char_class_type __m) const return (__c == '_' && (__m & __regex_word)); } +inline _LIBCPP_INLINE_VISIBILITY +bool __is_07(unsigned char c) +{ + return (c & 0xF8u) == +#if defined(__MVS__) && !defined(__NATIVE_ASCII_F) + 0xF0; +#else + 0x30; +#endif +} + +inline _LIBCPP_INLINE_VISIBILITY +bool __is_89(unsigned char c) +{ + return (c & 0xFEu) == +#if defined(__MVS__) && !defined(__NATIVE_ASCII_F) + 0xF8; +#else + 0x38; +#endif +} + +inline _LIBCPP_INLINE_VISIBILITY +unsigned char __to_lower(unsigned char c) +{ +#if defined(__MVS__) && !defined(__NATIVE_ASCII_F) + return c & 0xBF; +#else + return c | 0x20; +#endif +} + template <class _CharT> int regex_traits<_CharT>::__regex_traits_value(unsigned char __ch, int __radix) { - if ((__ch & 0xF8u) == 0x30) // '0' <= __ch && __ch <= '7' + if (__is_07(__ch)) // '0' <= __ch && __ch <= '7' return __ch - '0'; if (__radix != 8) { - if ((__ch & 0xFEu) == 0x38) // '8' <= __ch && __ch <= '9' + if (__is_89(__ch)) // '8' <= __ch && __ch <= '9' return __ch - '0'; if (__radix == 16) { - __ch |= 0x20; // tolower + __ch = __to_lower(__ch); // tolower if ('a' <= __ch && __ch <= 'f') return __ch - ('a' - 10); } diff --git contrib/llvm-project/libcxx/include/semaphore contrib/llvm-project/libcxx/include/semaphore index 2c2518bce46a..7dffc94b13ba 100644 --- contrib/llvm-project/libcxx/include/semaphore +++ contrib/llvm-project/libcxx/include/semaphore @@ -47,8 +47,10 @@ using binary_semaphore = counting_semaphore<1>; #include <__availability> #include <__config> +#include <__thread/timed_backoff_policy.h> #include <__threading_support> #include <atomic> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/sstream contrib/llvm-project/libcxx/include/sstream index e63d1434ac76..6ad624a93a65 100644 --- contrib/llvm-project/libcxx/include/sstream +++ contrib/llvm-project/libcxx/include/sstream @@ -184,6 +184,7 @@ typedef basic_stringstream<wchar_t> wstringstream; #include <istream> #include <ostream> #include <string> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/stack contrib/llvm-project/libcxx/include/stack index 5d959c33c742..ad65d7b29b4f 100644 --- contrib/llvm-project/libcxx/include/stack +++ contrib/llvm-project/libcxx/include/stack @@ -41,11 +41,14 @@ public: explicit stack(const container_type& c); explicit stack(container_type&& c); + template <class InputIterator> stack(InputIterator first, InputIterator last); // since C++23 template <class Alloc> explicit stack(const Alloc& a); template <class Alloc> stack(const container_type& c, const Alloc& a); template <class Alloc> stack(container_type&& c, const Alloc& a); template <class Alloc> stack(const stack& c, const Alloc& a); template <class Alloc> stack(stack&& c, const Alloc& a); + template<class InputIterator, class Alloc> + stack(InputIterator first, InputIterator last, const Alloc&); // since C++23 bool empty() const; size_type size() const; @@ -63,9 +66,17 @@ public: template<class Container> stack(Container) -> stack<typename Container::value_type, Container>; // C++17 +template<class InputIterator> + stack(InputIterator, InputIterator) -> stack<iter-value-type<InputIterator>>; // since C++23 + template<class Container, class Allocator> stack(Container, Allocator) -> stack<typename Container::value_type, Container>; // C++17 +template<class InputIterator, class Allocator> + stack(InputIterator, InputIterator, Allocator) + -> stack<iter-value-type<InputIterator>, + deque<iter-value-type<InputIterator>, Allocator>>; // since C++23 + template <class T, class Container> bool operator==(const stack<T, Container>& x, const stack<T, Container>& y); template <class T, class Container> @@ -88,9 +99,12 @@ template <class T, class Container> */ #include <__config> +#include <__iterator/iterator_traits.h> #include <__memory/uses_allocator.h> #include <__utility/forward.h> #include <deque> +#include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -183,6 +197,20 @@ public: : c(_VSTD::move(__s.c), __a) {} #endif // _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 20 + template <class _InputIterator, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> + _LIBCPP_HIDE_FROM_ABI + stack(_InputIterator __first, _InputIterator __last) : c(__first, __last) {} + + template <class _InputIterator, + class _Alloc, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>> + _LIBCPP_HIDE_FROM_ABI + stack(_InputIterator __first, _InputIterator __last, const _Alloc& __alloc) : c(__first, __last, __alloc) {} +#endif + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool empty() const {return c.empty();} _LIBCPP_INLINE_VISIBILITY @@ -231,7 +259,7 @@ public: operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y); }; -#if _LIBCPP_STD_VER >= 17 +#if _LIBCPP_STD_VER > 14 template<class _Container, class = enable_if_t<!__is_allocator<_Container>::value> > @@ -247,6 +275,20 @@ stack(_Container, _Alloc) -> stack<typename _Container::value_type, _Container>; #endif +#if _LIBCPP_STD_VER > 20 +template<class _InputIterator, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> +stack(_InputIterator, _InputIterator) + -> stack<__iter_value_type<_InputIterator>>; + +template<class _InputIterator, + class _Alloc, + class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = __enable_if_t<__is_allocator<_Alloc>::value>> +stack(_InputIterator, _InputIterator, _Alloc) + -> stack<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>; +#endif + template <class _Tp, class _Container> inline _LIBCPP_INLINE_VISIBILITY bool diff --git contrib/llvm-project/libcxx/include/stdexcept contrib/llvm-project/libcxx/include/stdexcept index c1dc05669bb9..5df2050ee4ec 100644 --- contrib/llvm-project/libcxx/include/stdexcept +++ contrib/llvm-project/libcxx/include/stdexcept @@ -42,9 +42,9 @@ public: */ #include <__config> +#include <cstdlib> #include <exception> #include <iosfwd> // for string forward decl -#include <cstdlib> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/streambuf contrib/llvm-project/libcxx/include/streambuf index db3078d809a5..9874ec2ce499 100644 --- contrib/llvm-project/libcxx/include/streambuf +++ contrib/llvm-project/libcxx/include/streambuf @@ -108,8 +108,10 @@ protected: */ #include <__config> +#include <cstdint> #include <ios> #include <iosfwd> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/string contrib/llvm-project/libcxx/include/string index 9049d7acbb9b..3616de8a214d 100644 --- contrib/llvm-project/libcxx/include/string +++ contrib/llvm-project/libcxx/include/string @@ -158,6 +158,9 @@ public: void resize(size_type n, value_type c); void resize(size_type n); + template<class Operation> + constexpr void resize_and_overwrite(size_type n, Operation op); // since C++23 + void reserve(size_type res_arg); void reserve(); // deprecated in C++20 void shrink_to_fit(); @@ -615,6 +618,7 @@ operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&)) +#ifndef _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS template <bool> struct __basic_string_common; @@ -624,6 +628,7 @@ struct __basic_string_common<true> { _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const; _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const; }; +#endif template <class _Iter> struct __string_is_trivial_iterator : public false_type {}; @@ -677,7 +682,9 @@ class _LIBCPP_PREFERRED_NAME(u32string) #endif basic_string +#ifndef _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS : private __basic_string_common<true> // This base class is historical, but it needs to remain for ABI compatibility +#endif { public: typedef basic_string __self; @@ -826,10 +833,7 @@ public: basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); __init(__s, traits_type::length(__s)); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > @@ -973,6 +977,16 @@ public: _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());} void reserve(size_type __requested_capacity); + +#if _LIBCPP_STD_VER > 20 + template <class _Op> + _LIBCPP_HIDE_FROM_ABI constexpr + void resize_and_overwrite(size_type __n, _Op __op) { + __resize_default_init(__n); + __erase_to_end(_VSTD::move(__op)(data(), _LIBCPP_AUTO_CAST(__n))); + } +#endif + _LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n); _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY @@ -1455,6 +1469,11 @@ public: #endif // _LIBCPP_DEBUG_LEVEL == 2 private: + _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { + // SSO is disabled during constant evaluation because `__is_long` isn't constexpr friendly + return !__libcpp_is_constant_evaluated() && (__sz < __min_cap); + } + _LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() _NOEXCEPT {return __r_.second();} @@ -1714,20 +1733,12 @@ private: _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - __basic_string_common<true>::__throw_length_error(); -#else - _VSTD::abort(); -#endif + _VSTD::__throw_length_error("basic_string"); } _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_out_of_range() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - __basic_string_common<true>::__throw_out_of_range(); -#else - _VSTD::abort(); -#endif + _VSTD::__throw_out_of_range("basic_string"); } friend basic_string operator+<>(const basic_string&, const basic_string&); @@ -1827,10 +1838,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) : __r_(__default_init_tag(), __default_init_tag()) { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __zero(); } @@ -1844,10 +1852,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __ #endif : __r_(__default_init_tag(), __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __zero(); } @@ -1857,9 +1862,9 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __reserve) { if (__reserve > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__reserve < __min_cap) + if (__fits_in_sso(__reserve)) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -1881,9 +1886,9 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) { if (__sz > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__sz < __min_cap) + if (__fits_in_sso(__sz)) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -1907,10 +1912,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); __init(__s, traits_type::length(__s)); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1918,12 +1920,9 @@ inline basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) : __r_(__default_init_tag(), __default_init_tag()) { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); - __init(__s, __n); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); + __init(__s, __n); + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1933,10 +1932,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_ { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); __init(__s, __n); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1948,11 +1944,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st else __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); - -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -1965,22 +1957,19 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( else __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( const value_type* __s, size_type __sz) { pointer __p; - if (__sz < __min_cap) { + if (__fits_in_sso(__sz)) { __p = __get_short_pointer(); __set_short_size(__sz); } else { if (__sz > max_size()) - this->__throw_length_error(); + __throw_length_error(); size_t __cap = __recommend(__sz); __p = __alloc_traits::allocate(__alloc(), __cap + 1); __set_long_pointer(__p); @@ -2003,12 +1992,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) : __r_(_VSTD::move(__str.__r_)) { __str.__zero(); + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) { - __get_db()->__insert_c(this); - if (__is_long()) - __get_db()->swap(this, &__str); - } + if (!__libcpp_is_constant_evaluated() && __is_long()) + __get_db()->swap(this, &__str); #endif } @@ -2024,12 +2011,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, co __r_.first().__r = __str.__r_.first().__r; __str.__zero(); } + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) { - __get_db()->__insert_c(this); - if (__is_long()) - __get_db()->swap(this, &__str); - } + if (!__libcpp_is_constant_evaluated() && __is_long()) + __get_db()->swap(this, &__str); #endif } @@ -2040,9 +2025,9 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) { if (__n > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__n < __min_cap) + if (__fits_in_sso(__n)) { __set_short_size(__n); __p = __get_short_pointer(); @@ -2065,10 +2050,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __ : __r_(__default_init_tag(), __default_init_tag()) { __init(__n, __c); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2077,10 +2059,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __ : __r_(__default_init_tag(), __a) { __init(__n, __c); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2091,12 +2070,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st { size_type __str_sz = __str.size(); if (__pos > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos)); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2107,12 +2083,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st { size_type __str_sz = __str.size(); if (__pos > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __init(__str.data() + __pos, __str_sz - __pos); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2124,10 +2097,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( __self_view __sv0 = __t; __self_view __sv = __sv0.substr(__pos, __n); __init(__sv.data(), __sv.size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2137,10 +2107,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2150,10 +2117,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _ { __self_view __sv = __t; __init(__sv.data(), __sv.size()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2192,9 +2156,9 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For { size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__sz > max_size()) - this->__throw_length_error(); + __throw_length_error(); pointer __p; - if (__sz < __min_cap) + if (__fits_in_sso(__sz)) { __set_short_size(__sz); __p = __get_short_pointer(); @@ -2233,10 +2197,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, : __r_(__default_init_tag(), __default_init_tag()) { __init(__first, __last); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2247,10 +2208,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, : __r_(__default_init_tag(), __a) { __init(__first, __last); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } #ifndef _LIBCPP_CXX03_LANG @@ -2262,10 +2220,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( : __r_(__default_init_tag(), __default_init_tag()) { __init(__il.begin(), __il.end()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _CharT, class _Traits, class _Allocator> @@ -2276,10 +2231,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( : __r_(__default_init_tag(), __a) { __init(__il.begin(), __il.end()); -#if _LIBCPP_DEBUG_LEVEL == 2 - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } #endif // _LIBCPP_CXX03_LANG @@ -2303,7 +2255,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace { size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap - 1) - this->__throw_length_error(); + __throw_length_error(); pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : @@ -2335,7 +2287,7 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t { size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap) - this->__throw_length_error(); + __throw_length_error(); pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : @@ -2398,7 +2350,7 @@ basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); - return (__builtin_constant_p(__n) && __n < __min_cap) + return (__builtin_constant_p(__n) && __fits_in_sso(__n)) ? __assign_short(__s, __n) : __assign_external(__s, __n); } @@ -2567,7 +2519,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz { size_type __sz = __str.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); } @@ -2584,7 +2536,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p __self_view __sv = __t; size_type __sz = __sv.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); } @@ -2601,7 +2553,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); return __builtin_constant_p(*__s) - ? (traits_type::length(__s) < __min_cap + ? (__fits_in_sso(traits_type::length(__s)) ? __assign_short(__s, traits_type::length(__s)) : __assign_external(__s, traits_type::length(__s))) : __assign_external(__s); @@ -2753,7 +2705,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz { size_type __sz = __str.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos)); } @@ -2769,7 +2721,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __p __self_view __sv = __t; size_type __sz = __sv.size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); } @@ -2790,7 +2742,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr"); size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); size_type __cap = capacity(); if (__cap - __sz >= __n) { @@ -2821,7 +2773,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n { size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); if (__n) { size_type __cap = capacity(); @@ -2927,7 +2879,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_ { size_type __str_sz = __str.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); } @@ -2944,7 +2896,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& _ __self_view __sv = __t; size_type __str_sz = __sv.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); } @@ -3005,7 +2957,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __n1 = _VSTD::min(__n1, __sz - __pos); size_type __cap = capacity(); if (__cap - __sz + __n1 >= __n2) @@ -3052,7 +3004,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ { size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); __n1 = _VSTD::min(__n1, __sz - __pos); size_type __cap = capacity(); value_type* __p; @@ -3086,7 +3038,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it _InputIterator __j1, _InputIterator __j2) { const basic_string __temp(__j1, __j2, __alloc()); - return this->replace(__i1, __i2, __temp); + return replace(__i1, __i2, __temp); } template <class _CharT, class _Traits, class _Allocator> @@ -3104,7 +3056,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ { size_type __str_sz = __str.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); } @@ -3121,7 +3073,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ __self_view __sv = __t; size_type __str_sz = __sv.size(); if (__pos2 > __str_sz) - this->__throw_out_of_range(); + __throw_out_of_range(); return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); } @@ -3191,7 +3143,8 @@ template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) { - if (__pos > size()) this->__throw_out_of_range(); + if (__pos > size()) + __throw_out_of_range(); if (__n == npos) { __erase_to_end(__pos); } else { @@ -3307,12 +3260,13 @@ void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) { if (__requested_capacity > max_size()) - this->__throw_length_error(); + __throw_length_error(); -#if _LIBCPP_STD_VER > 17 - // Reserve never shrinks as of C++20. - if (__requested_capacity <= capacity()) return; -#endif + // Make sure reserve(n) never shrinks. This is technically only required in C++20 + // and later (since P0966R1), however we provide consistent behavior in all Standard + // modes because this function is instantiated in the shared library. + if (__requested_capacity <= capacity()) + return; size_type __target_capacity = _VSTD::max(__requested_capacity, size()); __target_capacity = __recommend(__target_capacity); @@ -3413,7 +3367,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const { if (__n >= size()) - this->__throw_out_of_range(); + __throw_out_of_range(); return (*this)[__n]; } @@ -3422,7 +3376,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) { if (__n >= size()) - this->__throw_out_of_range(); + __throw_out_of_range(); return (*this)[__n]; } @@ -3468,7 +3422,7 @@ basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, { size_type __sz = size(); if (__pos > __sz) - this->__throw_out_of_range(); + __throw_out_of_range(); size_type __rlen = _VSTD::min(__n, __sz - __pos); traits_type::copy(__s, data() + __pos, __rlen); return __rlen; @@ -3912,7 +3866,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); size_type __sz = size(); if (__pos1 > __sz || __n2 == npos) - this->__throw_out_of_range(); + __throw_out_of_range(); size_type __rlen = _VSTD::min(__n1, __sz - __pos1); int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); if (__r == 0) @@ -3976,7 +3930,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __pos2, size_type __n2) const { - return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); + return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); } template <class _CharT, class _Traits, class _Allocator> @@ -4490,16 +4444,16 @@ template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const { - return this->data() <= _VSTD::__to_address(__i->base()) && - _VSTD::__to_address(__i->base()) < this->data() + this->size(); + return data() <= _VSTD::__to_address(__i->base()) && + _VSTD::__to_address(__i->base()) < data() + size(); } template<class _CharT, class _Traits, class _Allocator> bool basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const { - return this->data() < _VSTD::__to_address(__i->base()) && - _VSTD::__to_address(__i->base()) <= this->data() + this->size(); + return data() < _VSTD::__to_address(__i->base()) && + _VSTD::__to_address(__i->base()) <= data() + size(); } template<class _CharT, class _Traits, class _Allocator> @@ -4507,7 +4461,7 @@ bool basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const { const value_type* __p = _VSTD::__to_address(__i->base()) + __n; - return this->data() <= __p && __p <= this->data() + this->size(); + return data() <= __p && __p <= data() + size(); } template<class _CharT, class _Traits, class _Allocator> @@ -4515,7 +4469,7 @@ bool basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const { const value_type* __p = _VSTD::__to_address(__i->base()) + __n; - return this->data() <= __p && __p < this->data() + this->size(); + return data() <= __p && __p < data() + size(); } #endif // _LIBCPP_DEBUG_LEVEL == 2 diff --git contrib/llvm-project/libcxx/include/strstream contrib/llvm-project/libcxx/include/strstream index a5f17a9dc319..c34a5628b634 100644 --- contrib/llvm-project/libcxx/include/strstream +++ contrib/llvm-project/libcxx/include/strstream @@ -132,6 +132,7 @@ private: #include <__config> #include <istream> #include <ostream> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/system_error contrib/llvm-project/libcxx/include/system_error index 059fa0e2d511..6d3a6ca65038 100644 --- contrib/llvm-project/libcxx/include/system_error +++ contrib/llvm-project/libcxx/include/system_error @@ -150,6 +150,7 @@ template <> struct hash<std::error_condition>; #include <stdexcept> #include <string> #include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/thread contrib/llvm-project/libcxx/include/thread index a4632f6fe524..27756e42cdcb 100644 --- contrib/llvm-project/libcxx/include/thread +++ contrib/llvm-project/libcxx/include/thread @@ -87,6 +87,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); #include <__functional_base> #include <__mutex_base> #include <__thread/poll_with_backoff.h> +#include <__thread/timed_backoff_policy.h> #include <__threading_support> #include <__utility/forward.h> #include <chrono> @@ -97,6 +98,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); #include <system_error> #include <tuple> #include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/tuple contrib/llvm-project/libcxx/include/tuple index 8ee5c2eef51d..5cf120fec359 100644 --- contrib/llvm-project/libcxx/include/tuple +++ contrib/llvm-project/libcxx/include/tuple @@ -73,6 +73,19 @@ public: void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20 }; + +template<class... TTypes, class... UTypes, template<class> class TQual, template<class> class UQual> // since C++23 + requires requires { typename tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; } +struct basic_common_reference<tuple<TTypes...>, tuple<UTypes...>, TQual, UQual> { + using type = tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; +}; + +template<class... TTypes, class... UTypes> // since C++23 + requires requires { typename tuple<common_type_t<TTypes, UTypes>...>; } +struct common_type<tuple<TTypes...>, tuple<UTypes...>> { + using type = tuple<common_type_t<TTypes, UTypes>...>; +}; + template <class ...T> tuple(T...) -> tuple<T...>; // since C++17 template <class T1, class T2> @@ -1103,7 +1116,21 @@ public: void swap(tuple&) _NOEXCEPT {} }; -#if _LIBCPP_STD_VER >= 17 +#if _LIBCPP_STD_VER > 20 +template <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual> + requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; } +struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> { + using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; +}; + +template <class... _TTypes, class... _UTypes> + requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; } +struct common_type<tuple<_TTypes...>, tuple<_UTypes...>> { + using type = tuple<common_type_t<_TTypes, _UTypes>...>; +}; +#endif + +#if _LIBCPP_STD_VER > 14 template <class ..._Tp> tuple(_Tp...) -> tuple<_Tp...>; template <class _Tp1, class _Tp2> diff --git contrib/llvm-project/libcxx/include/type_traits contrib/llvm-project/libcxx/include/type_traits index 155b775e4929..b4010851f133 100644 --- contrib/llvm-project/libcxx/include/type_traits +++ contrib/llvm-project/libcxx/include/type_traits @@ -2318,7 +2318,7 @@ struct __common_type_impl {}; // Clang provides variadic templates in C++03 as an extension. #if !defined(_LIBCPP_CXX03_LANG) || defined(__clang__) # define _LIBCPP_OPTIONAL_PACK(...) , __VA_ARGS__ -template <class... Tp> +template <class... _Tp> struct __common_types; template <class... _Tp> struct _LIBCPP_TEMPLATE_VIS common_type; diff --git contrib/llvm-project/libcxx/include/typeindex contrib/llvm-project/libcxx/include/typeindex index 790aea4d4763..ede0c7fb25c2 100644 --- contrib/llvm-project/libcxx/include/typeindex +++ contrib/llvm-project/libcxx/include/typeindex @@ -49,6 +49,7 @@ struct hash<type_index> #include <__functional_base> #include <compare> #include <typeinfo> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/unordered_map contrib/llvm-project/libcxx/include/unordered_map index 53ddb95663d1..361db707d246 100644 --- contrib/llvm-project/libcxx/include/unordered_map +++ contrib/llvm-project/libcxx/include/unordered_map @@ -517,8 +517,9 @@ template <class Key, class T, class Hash, class Pred, class Alloc> #include <__config> #include <__debug> #include <__functional/is_transparent.h> -#include <__iterator/iterator_traits.h> #include <__hash_table> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> #include <__node_handle> #include <__utility/forward.h> #include <compare> @@ -1068,11 +1069,9 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_map() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - } + { + _VSTD::__debug_db_insert_c(this); + } explicit unordered_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_map(size_type __n, const hasher& __hf, @@ -1188,13 +1187,10 @@ public: {return __table_.__insert_unique(__x);} iterator insert(const_iterator __p, const value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered_map::insert(const_iterator, const value_type&) called with an iterator not " + "referring to this unordered_map"); ((void)__p); -#endif return insert(__x).first; } @@ -1212,13 +1208,10 @@ public: {return __table_.__insert_unique(_VSTD::move(__x));} iterator insert(const_iterator __p, value_type&& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" + " referring to this unordered_map"); ((void)__p); -#endif return __table_.__insert_unique(_VSTD::move(__x)).first; } @@ -1233,13 +1226,10 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, _Pp&& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" + " referring to this unordered_map"); ((void)__p); -#endif return insert(_VSTD::forward<_Pp>(__x)).first; } @@ -1252,13 +1242,10 @@ public: template <class... _Args> _LIBCPP_INLINE_VISIBILITY iterator emplace_hint(const_iterator __p, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered_map"); ((void)__p); -#endif return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; } @@ -1287,13 +1274,10 @@ public: _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__h) == this, - "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this, + "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" + " referring to this unordered_map"); ((void)__h); -#endif return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; } @@ -1301,13 +1285,10 @@ public: _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__h) == this, - "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" - " referring to this unordered_map"); -#else + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this, + "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" + " referring to this unordered_map"); ((void)__h); -#endif return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first; } @@ -1625,9 +1606,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -1637,9 +1616,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -1649,9 +1626,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const allocator_type& __a) : __table_(typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> @@ -1659,9 +1634,7 @@ template <class _InputIterator> unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__first, __last); } @@ -1672,9 +1645,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -1686,9 +1657,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -1698,9 +1667,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const unordered_map& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1710,9 +1677,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const unordered_map& __u, const allocator_type& __a) : __table_(__u.__table_, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1726,9 +1691,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1737,9 +1702,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( unordered_map&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a != __u.get_allocator()) { iterator __i = __u.begin(); @@ -1750,7 +1713,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( } #if _LIBCPP_DEBUG_LEVEL == 2 else - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1758,9 +1721,7 @@ template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__il.begin(), __il.end()); } @@ -1770,9 +1731,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1783,9 +1742,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -2003,11 +1960,9 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_multimap() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - } + { + _VSTD::__debug_db_insert_c(this); + } explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_multimap(size_type __n, const hasher& __hf, @@ -2427,9 +2382,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -2439,9 +2392,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -2450,9 +2401,7 @@ template <class _InputIterator> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__first, __last); } @@ -2463,9 +2412,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -2477,9 +2424,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -2490,9 +2435,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const allocator_type& __a) : __table_(typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> @@ -2500,9 +2443,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const unordered_multimap& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -2512,9 +2453,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const unordered_multimap& __u, const allocator_type& __a) : __table_(__u.__table_, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -2528,9 +2467,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -2539,9 +2478,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( unordered_multimap&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a != __u.get_allocator()) { iterator __i = __u.begin(); @@ -2553,7 +2490,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( } #if _LIBCPP_DEBUG_LEVEL == 2 else - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -2561,9 +2498,7 @@ template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__il.begin(), __il.end()); } @@ -2573,9 +2508,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -2586,9 +2519,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } diff --git contrib/llvm-project/libcxx/include/unordered_set contrib/llvm-project/libcxx/include/unordered_set index 1b62e31bb918..29a19f2f0cb5 100644 --- contrib/llvm-project/libcxx/include/unordered_set +++ contrib/llvm-project/libcxx/include/unordered_set @@ -463,6 +463,7 @@ template <class Value, class Hash, class Pred, class Alloc> #include <__debug> #include <__functional/is_transparent.h> #include <__hash_table> +#include <__memory/addressof.h> #include <__node_handle> #include <__utility/forward.h> #include <compare> @@ -524,11 +525,9 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_set() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - } + { + _VSTD::__debug_db_insert_c(this); + } explicit unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); #if _LIBCPP_STD_VER > 11 @@ -642,7 +641,7 @@ public: #if _LIBCPP_DEBUG_LEVEL == 2 iterator emplace_hint(const_iterator __p, _Args&&... __args) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not" " referring to this unordered_set"); return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; @@ -659,7 +658,7 @@ public: #if _LIBCPP_DEBUG_LEVEL == 2 iterator insert(const_iterator __p, value_type&& __x) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, "unordered_set::insert(const_iterator, value_type&&) called with an iterator not" " referring to this unordered_set"); return insert(_VSTD::move(__x)).first; @@ -680,7 +679,7 @@ public: #if _LIBCPP_DEBUG_LEVEL == 2 iterator insert(const_iterator __p, const value_type& __x) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, "unordered_set::insert(const_iterator, const value_type&) called with an iterator not" " referring to this unordered_set"); return insert(__x).first; @@ -935,9 +934,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -946,9 +943,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -957,9 +952,7 @@ template <class _InputIterator> unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__first, __last); } @@ -970,9 +963,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -984,9 +975,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -997,9 +986,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const allocator_type& __a) : __table_(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _Value, class _Hash, class _Pred, class _Alloc> @@ -1007,9 +994,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const unordered_set& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1019,9 +1004,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const unordered_set& __u, const allocator_type& __a) : __table_(__u.__table_, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1035,9 +1018,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1046,9 +1029,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( unordered_set&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a != __u.get_allocator()) { iterator __i = __u.begin(); @@ -1057,7 +1038,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( } #if _LIBCPP_DEBUG_LEVEL == 2 else - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1065,9 +1046,7 @@ template <class _Value, class _Hash, class _Pred, class _Alloc> unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__il.begin(), __il.end()); } @@ -1077,9 +1056,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1090,9 +1067,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1223,11 +1198,9 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_multiset() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - } + { + _VSTD::__debug_db_insert_c(this); + } explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_multiset(size_type __n, const hasher& __hf, @@ -1601,9 +1574,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -1613,9 +1584,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); } @@ -1624,9 +1593,7 @@ template <class _InputIterator> unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__first, __last); } @@ -1637,9 +1604,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -1651,9 +1616,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__first, __last); } @@ -1664,9 +1627,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const allocator_type& __a) : __table_(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } template <class _Value, class _Hash, class _Pred, class _Alloc> @@ -1674,9 +1635,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const unordered_multiset& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1686,9 +1645,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const unordered_multiset& __u, const allocator_type& __a) : __table_(__u.__table_, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1702,9 +1659,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1713,9 +1670,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( unordered_multiset&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a != __u.get_allocator()) { iterator __i = __u.begin(); @@ -1724,7 +1679,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( } #if _LIBCPP_DEBUG_LEVEL == 2 else - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1732,9 +1687,7 @@ template <class _Value, class _Hash, class _Pred, class _Alloc> unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); insert(__il.begin(), __il.end()); } @@ -1744,9 +1697,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1757,9 +1708,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); __table_.rehash(__n); insert(__il.begin(), __il.end()); } diff --git contrib/llvm-project/libcxx/include/valarray contrib/llvm-project/libcxx/include/valarray index 909e0422c476..a55d921872ba 100644 --- contrib/llvm-project/libcxx/include/valarray +++ contrib/llvm-project/libcxx/include/valarray @@ -348,6 +348,7 @@ template <class T> unspecified2 end(const valarray<T>& v); #include <functional> #include <initializer_list> #include <new> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git contrib/llvm-project/libcxx/include/vector contrib/llvm-project/libcxx/include/vector index 9b0092cfdbd9..fd0fb0db2756 100644 --- contrib/llvm-project/libcxx/include/vector +++ contrib/llvm-project/libcxx/include/vector @@ -271,8 +271,8 @@ erase_if(vector<T, Allocator>& c, Predicate pred); // C++20 */ -#include <__config> #include <__bit_reference> +#include <__config> #include <__debug> #include <__functional_base> #include <__iterator/iterator_traits.h> @@ -373,11 +373,9 @@ public: _LIBCPP_INLINE_VISIBILITY vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) - { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - } + { + _VSTD::__debug_db_insert_c(this); + } _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) @@ -386,9 +384,7 @@ public: #endif : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); } explicit vector(size_type __n); #if _LIBCPP_STD_VER > 11 @@ -400,9 +396,7 @@ public: vector(size_type __n, const value_type& __x, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__n > 0) { __vallocate(__n); @@ -1101,9 +1095,7 @@ vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x) template <class _Tp, class _Allocator> vector<_Tp, _Allocator>::vector(size_type __n) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__n > 0) { __vallocate(__n); @@ -1116,9 +1108,7 @@ template <class _Tp, class _Allocator> vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__n > 0) { __vallocate(__n); @@ -1130,9 +1120,7 @@ vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a) template <class _Tp, class _Allocator> vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__n > 0) { __vallocate(__n); @@ -1150,9 +1138,7 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, typename iterator_traits<_InputIterator>::reference>::value, _InputIterator>::type __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __first != __last; ++__first) __emplace_back(*__first); } @@ -1167,9 +1153,7 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, c typename iterator_traits<_InputIterator>::reference>::value>::type*) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); for (; __first != __last; ++__first) __emplace_back(*__first); } @@ -1183,9 +1167,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, typename iterator_traits<_ForwardIterator>::reference>::value, _ForwardIterator>::type __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n > 0) { @@ -1203,9 +1185,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las typename iterator_traits<_ForwardIterator>::reference>::value>::type*) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n > 0) { @@ -1218,9 +1198,7 @@ template <class _Tp, class _Allocator> vector<_Tp, _Allocator>::vector(const vector& __x) : __base(__alloc_traits::select_on_container_copy_construction(__x.__alloc())) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); size_type __n = __x.size(); if (__n > 0) { @@ -1233,9 +1211,7 @@ template <class _Tp, class _Allocator> vector<_Tp, _Allocator>::vector(const vector& __x, const __identity_t<allocator_type>& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); size_type __n = __x.size(); if (__n > 0) { @@ -1256,8 +1232,8 @@ vector<_Tp, _Allocator>::vector(vector&& __x) #endif : __base(_VSTD::move(__x.__alloc())) { + _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); __get_db()->swap(this, _VSTD::addressof(__x)); #endif this->__begin_ = __x.__begin_; @@ -1271,9 +1247,7 @@ inline _LIBCPP_INLINE_VISIBILITY vector<_Tp, _Allocator>::vector(vector&& __x, const __identity_t<allocator_type>& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__a == __x.__alloc()) { this->__begin_ = __x.__begin_; @@ -1295,9 +1269,7 @@ template <class _Tp, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__il.size() > 0) { __vallocate(__il.size()); @@ -1310,9 +1282,7 @@ inline _LIBCPP_INLINE_VISIBILITY vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif + _VSTD::__debug_db_insert_c(this); if (__il.size() > 0) { __vallocate(__il.size()); @@ -1677,11 +1647,8 @@ inline _LIBCPP_INLINE_VISIBILITY typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __position) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::erase(iterator) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::erase(iterator) called with an iterator not referring to this vector"); _LIBCPP_ASSERT(__position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator"); difference_type __ps = __position - cbegin(); @@ -1696,14 +1663,11 @@ template <class _Tp, class _Allocator> typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, - "vector::erase(iterator, iterator) called with an iterator not" - " referring to this vector"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, - "vector::erase(iterator, iterator) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, + "vector::erase(iterator, iterator) called with an iterator not referring to this vector"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, + "vector::erase(iterator, iterator) called with an iterator not referring to this vector"); + _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range"); pointer __p = this->__begin_ + (__first - begin()); if (__first != __last) { @@ -1737,11 +1701,8 @@ template <class _Tp, class _Allocator> typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::insert(iterator, x) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::insert(iterator, x) called with an iterator not referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1774,11 +1735,8 @@ template <class _Tp, class _Allocator> typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::insert(iterator, x) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::insert(iterator, x) called with an iterator not referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1807,11 +1765,8 @@ template <class... _Args> typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::emplace(iterator, x) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::emplace(iterator, x) called with an iterator not referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1842,11 +1797,8 @@ template <class _Tp, class _Allocator> typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::insert(iterator, n, x) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::insert(iterator, n, x) called with an iterator not referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (__n > 0) { @@ -1893,11 +1845,8 @@ typename enable_if >::type vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::insert(iterator, range) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::insert(iterator, range) called with an iterator not referring to this vector"); difference_type __off = __position - begin(); pointer __p = this->__begin_ + __off; allocator_type& __a = this->__alloc(); @@ -1946,11 +1895,8 @@ typename enable_if >::type vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, - "vector::insert(iterator, range) called with an iterator not" - " referring to this vector"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__position)) == this, + "vector::insert(iterator, range) called with an iterator not referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); difference_type __n = _VSTD::distance(__first, __last); if (__n > 0) diff --git contrib/llvm-project/libcxx/include/version contrib/llvm-project/libcxx/include/version index 574dfe47b58f..0c2365612853 100644 --- contrib/llvm-project/libcxx/include/version +++ contrib/llvm-project/libcxx/include/version @@ -14,7 +14,9 @@ version synopsis Macro name Value Headers +__cpp_lib_adaptor_iterator_pair_constructor 202106L <queue> <stack> __cpp_lib_addressof_constexpr 201603L <memory> +__cpp_lib_allocate_at_least 202106L <memory> __cpp_lib_allocator_traits_is_always_equal 201411L <deque> <forward_list> <list> <map> <memory> <scoped_allocator> <set> <string> <unordered_map> @@ -24,6 +26,8 @@ __cpp_lib_apply 201603L <tuple> __cpp_lib_array_constexpr 201811L <array> <iterator> 201603L // C++17 __cpp_lib_as_const 201510L <utility> +__cpp_lib_associative_heterogeneous_erasure 202110L <map> <set> <unordered_map> + <unordered_set> __cpp_lib_assume_aligned 201811L <memory> __cpp_lib_atomic_flag_test 201907L <atomic> __cpp_lib_atomic_float 201711L <atomic> @@ -60,6 +64,7 @@ __cpp_lib_constexpr_numeric 201911L <numeric> __cpp_lib_constexpr_string 201811L <string> __cpp_lib_constexpr_string_view 201811L <string_view> __cpp_lib_constexpr_tuple 201811L <tuple> +__cpp_lib_constexpr_typeinfo 202106L <typeinfo> __cpp_lib_constexpr_utility 201811L <utility> __cpp_lib_constexpr_vector 201907L <vector> __cpp_lib_coroutine 201902L <coroutine> @@ -87,6 +92,7 @@ __cpp_lib_integer_sequence 201304L <utility> __cpp_lib_integral_constant_callable 201304L <type_traits> __cpp_lib_interpolate 201902L <cmath> <numeric> __cpp_lib_invoke 201411L <functional> +__cpp_lib_invoke_r 202106L <functional> __cpp_lib_is_aggregate 201703L <type_traits> __cpp_lib_is_constant_evaluated 201811L <type_traits> __cpp_lib_is_final 201402L <type_traits> @@ -110,6 +116,7 @@ __cpp_lib_math_constants 201907L <numbers> __cpp_lib_math_special_functions 201603L <cmath> __cpp_lib_memory_resource 201603L <memory_resource> __cpp_lib_monadic_optional 202110L <optional> +__cpp_lib_move_only_function 202110L <functional> __cpp_lib_node_extract 201606L <map> <set> <unordered_map> <unordered_set> __cpp_lib_nonmember_container_access 201411L <array> <deque> <forward_list> @@ -119,11 +126,14 @@ __cpp_lib_nonmember_container_access 201411L <array> <deque> __cpp_lib_not_fn 201603L <functional> __cpp_lib_null_iterators 201304L <iterator> __cpp_lib_optional 201606L <optional> +__cpp_lib_out_ptr 202106L <memory> __cpp_lib_parallel_algorithm 201603L <algorithm> <numeric> -__cpp_lib_polymorphic_allocator 201902L <memory> +__cpp_lib_polymorphic_allocator 201902L <memory_resource> __cpp_lib_quoted_string_io 201304L <iomanip> __cpp_lib_ranges 201811L <algorithm> <functional> <iterator> <memory> <ranges> +__cpp_lib_ranges_starts_ends_with 202106L <algorithm> +__cpp_lib_ranges_zip 202110L <ranges> <tuple> <utility> __cpp_lib_raw_memory_algorithms 201606L <memory> __cpp_lib_remove_cvref 201711L <type_traits> __cpp_lib_result_of_sfinae 201210L <functional> <type_traits> @@ -139,11 +149,13 @@ __cpp_lib_shift 201806L <algorithm> __cpp_lib_smart_ptr_for_overwrite 202002L <memory> __cpp_lib_source_location 201907L <source_location> __cpp_lib_span 202002L <span> +__cpp_lib_spanstream 202106L <spanstream> __cpp_lib_ssize 201902L <iterator> __cpp_lib_stacktrace 202011L <stacktrace> __cpp_lib_starts_ends_with 201711L <string> <string_view> __cpp_lib_stdatomic_h 202011L <stdatomic.h> __cpp_lib_string_contains 202011L <string> <string_view> +__cpp_lib_string_resize_and_overwrite 202110L <string> __cpp_lib_string_udls 201304L <string> __cpp_lib_string_view 201803L <string> <string_view> 201606L // C++17 @@ -158,6 +170,7 @@ __cpp_lib_transparent_operators 201510L <functional> <me 201210L // C++14 __cpp_lib_tuple_element_t 201402L <tuple> __cpp_lib_tuples_by_type 201304L <tuple> <utility> +__cpp_lib_type_identity 201806L <type_traits> __cpp_lib_type_trait_variable_templates 201510L <type_traits> __cpp_lib_uncaught_exceptions 201411L <exception> __cpp_lib_unordered_map_try_emplace 201411L <unordered_map> @@ -342,16 +355,28 @@ __cpp_lib_void_t 201411L <type_traits> // # define __cpp_lib_three_way_comparison 201907L # define __cpp_lib_to_address 201711L # define __cpp_lib_to_array 201907L +# define __cpp_lib_type_identity 201806L # define __cpp_lib_unwrap_ref 201811L #endif #if _LIBCPP_STD_VER > 20 +# define __cpp_lib_adaptor_iterator_pair_constructor 202106L +// # define __cpp_lib_allocate_at_least 202106L +// # define __cpp_lib_associative_heterogeneous_erasure 202110L # define __cpp_lib_byteswap 202110L +// # define __cpp_lib_constexpr_typeinfo 202106L +// # define __cpp_lib_invoke_r 202106L # define __cpp_lib_is_scoped_enum 202011L # define __cpp_lib_monadic_optional 202110L +// # define __cpp_lib_move_only_function 202110L +// # define __cpp_lib_out_ptr 202106L +// # define __cpp_lib_ranges_starts_ends_with 202106L +// # define __cpp_lib_ranges_zip 202110L +// # define __cpp_lib_spanstream 202106L // # define __cpp_lib_stacktrace 202011L // # define __cpp_lib_stdatomic_h 202011L # define __cpp_lib_string_contains 202011L +# define __cpp_lib_string_resize_and_overwrite 202110L # define __cpp_lib_to_underlying 202102L #endif diff --git contrib/llvm-project/libcxx/src/atomic.cpp contrib/llvm-project/libcxx/src/atomic.cpp index 9b61a16106c2..250d33e98b02 100644 --- contrib/llvm-project/libcxx/src/atomic.cpp +++ contrib/llvm-project/libcxx/src/atomic.cpp @@ -9,9 +9,10 @@ #include <__config> #ifndef _LIBCPP_HAS_NO_THREADS -#include <climits> #include <atomic> +#include <climits> #include <functional> +#include <thread> #ifdef __linux__ diff --git contrib/llvm-project/libcxx/src/chrono.cpp contrib/llvm-project/libcxx/src/chrono.cpp index 5aa7af75894b..4f2d51042ff1 100644 --- contrib/llvm-project/libcxx/src/chrono.cpp +++ contrib/llvm-project/libcxx/src/chrono.cpp @@ -44,6 +44,10 @@ # endif #endif // defined(_LIBCPP_WIN32API) +#if defined(__Fuchsia__) +# include <zircon/syscalls.h> +#endif + #if __has_include(<mach/mach_time.h>) # include <mach/mach_time.h> #endif @@ -266,7 +270,18 @@ static steady_clock::time_point __libcpp_steady_clock_now() { return steady_clock::time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); } -#elif defined(CLOCK_MONOTONIC) +# elif defined(__Fuchsia__) + +static steady_clock::time_point __libcpp_steady_clock_now() noexcept { + // Implicitly link against the vDSO system call ABI without + // requiring the final link to specify -lzircon explicitly when + // statically linking libc++. +# pragma comment(lib, "zircon") + + return steady_clock::time_point(nanoseconds(_zx_clock_get_monotonic())); +} + +# elif defined(CLOCK_MONOTONIC) static steady_clock::time_point __libcpp_steady_clock_now() { struct timespec tp; @@ -275,9 +290,9 @@ static steady_clock::time_point __libcpp_steady_clock_now() { return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); } -#else -# error "Monotonic clock not implemented on this platform" -#endif +# else +# error "Monotonic clock not implemented on this platform" +# endif const bool steady_clock::is_steady; diff --git contrib/llvm-project/libcxx/src/chrono_system_time_init.h contrib/llvm-project/libcxx/src/chrono_system_time_init.h index 3c5a0c33a56a..b1bdc691b385 100644 --- contrib/llvm-project/libcxx/src/chrono_system_time_init.h +++ contrib/llvm-project/libcxx/src/chrono_system_time_init.h @@ -1,2 +1,2 @@ #pragma GCC system_header -GetSystemTimeInit GetSystemTimeAsFileTimeFunc _LIBCPP_INIT_PRIORITY_MAX; \ No newline at end of file +GetSystemTimeInit GetSystemTimeAsFileTimeFunc _LIBCPP_INIT_PRIORITY_MAX; diff --git contrib/llvm-project/libcxx/src/experimental/memory_resource_init_helper.h contrib/llvm-project/libcxx/src/experimental/memory_resource_init_helper.h index 2e1cae5ecc60..56b9da685878 100644 --- contrib/llvm-project/libcxx/src/experimental/memory_resource_init_helper.h +++ contrib/llvm-project/libcxx/src/experimental/memory_resource_init_helper.h @@ -1,2 +1,2 @@ #pragma GCC system_header -_LIBCPP_SAFE_STATIC ResourceInitHelper res_init _LIBCPP_INIT_PRIORITY_MAX; \ No newline at end of file +_LIBCPP_SAFE_STATIC ResourceInitHelper res_init _LIBCPP_INIT_PRIORITY_MAX; diff --git contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp index 90b255d9877f..fa793f68295b 100644 --- contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp +++ contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp @@ -9,97 +9,12 @@ #include "__config" #include "filesystem" #include "stack" -#if defined(_LIBCPP_WIN32API) -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include <windows.h> -#else -#include <dirent.h> -#endif #include <errno.h> #include "filesystem_common.h" _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -namespace detail { -namespace { - -#if !defined(_LIBCPP_WIN32API) - -#if defined(DT_BLK) -template <class DirEntT, class = decltype(DirEntT::d_type)> -static file_type get_file_type(DirEntT* ent, int) { - switch (ent->d_type) { - case DT_BLK: - return file_type::block; - case DT_CHR: - return file_type::character; - case DT_DIR: - return file_type::directory; - case DT_FIFO: - return file_type::fifo; - case DT_LNK: - return file_type::symlink; - case DT_REG: - return file_type::regular; - case DT_SOCK: - return file_type::socket; - // Unlike in lstat, hitting "unknown" here simply means that the underlying - // filesystem doesn't support d_type. Report is as 'none' so we correctly - // set the cache to empty. - case DT_UNKNOWN: - break; - } - return file_type::none; -} -#endif // defined(DT_BLK) - -template <class DirEntT> -static file_type get_file_type(DirEntT* ent, long) { - return file_type::none; -} - -static pair<string_view, file_type> posix_readdir(DIR* dir_stream, - error_code& ec) { - struct dirent* dir_entry_ptr = nullptr; - errno = 0; // zero errno in order to detect errors - ec.clear(); - if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) { - if (errno) - ec = capture_errno(); - return {}; - } else { - return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)}; - } -} -#else -// defined(_LIBCPP_WIN32API) - -static file_type get_file_type(const WIN32_FIND_DATAW& data) { - if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && - data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) - return file_type::symlink; - if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - return file_type::directory; - return file_type::regular; -} -static uintmax_t get_file_size(const WIN32_FIND_DATAW& data) { - return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow; -} -static file_time_type get_write_time(const WIN32_FIND_DATAW& data) { - ULARGE_INTEGER tmp; - const FILETIME& time = data.ftLastWriteTime; - tmp.u.LowPart = time.dwLowDateTime; - tmp.u.HighPart = time.dwHighDateTime; - return file_time_type(file_time_type::duration(tmp.QuadPart)); -} - -#endif - -} // namespace -} // namespace detail - using detail::ErrorHandler; #if defined(_LIBCPP_WIN32API) @@ -197,9 +112,9 @@ public: : __stream_(nullptr), __root_(root) { if ((__stream_ = ::opendir(root.c_str())) == nullptr) { ec = detail::capture_errno(); - const bool allow_eacess = + const bool allow_eacces = bool(opts & directory_options::skip_permission_denied); - if (allow_eacess && ec.value() == EACCES) + if (allow_eacces && ec.value() == EACCES) ec.clear(); return; } diff --git contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h index 717894e537d2..99bba2760dce 100644 --- contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h +++ contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h @@ -17,14 +17,22 @@ #include "cstdlib" #include "ctime" #include "filesystem" +#include "ratio" #include "system_error" +#if defined(_LIBCPP_WIN32API) +# define WIN32_LEAN_AND_MEAN +# define NOMINMAX +# include <windows.h> +#endif + #if !defined(_LIBCPP_WIN32API) -# include <unistd.h> +# include <dirent.h> // for DIR & friends +# include <fcntl.h> /* values for fchmodat */ # include <sys/stat.h> # include <sys/statvfs.h> # include <sys/time.h> // for ::utimes as used in __last_write_time -# include <fcntl.h> /* values for fchmodat */ +# include <unistd.h> #endif #include "../include/apple_availability.h" @@ -526,7 +534,76 @@ bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS, return posix_utimensat(p, TS, ec); #endif } -#endif /* !_LIBCPP_WIN32API */ + +#if defined(DT_BLK) +template <class DirEntT, class = decltype(DirEntT::d_type)> +static file_type get_file_type(DirEntT* ent, int) { + switch (ent->d_type) { + case DT_BLK: + return file_type::block; + case DT_CHR: + return file_type::character; + case DT_DIR: + return file_type::directory; + case DT_FIFO: + return file_type::fifo; + case DT_LNK: + return file_type::symlink; + case DT_REG: + return file_type::regular; + case DT_SOCK: + return file_type::socket; + // Unlike in lstat, hitting "unknown" here simply means that the underlying + // filesystem doesn't support d_type. Report is as 'none' so we correctly + // set the cache to empty. + case DT_UNKNOWN: + break; + } + return file_type::none; +} +#endif // defined(DT_BLK) + +template <class DirEntT> +static file_type get_file_type(DirEntT*, long) { + return file_type::none; +} + +static pair<string_view, file_type> posix_readdir(DIR* dir_stream, + error_code& ec) { + struct dirent* dir_entry_ptr = nullptr; + errno = 0; // zero errno in order to detect errors + ec.clear(); + if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) { + if (errno) + ec = capture_errno(); + return {}; + } else { + return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)}; + } +} + +#else // _LIBCPP_WIN32API + +static file_type get_file_type(const WIN32_FIND_DATAW& data) { + if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && + data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) + return file_type::symlink; + if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + return file_type::directory; + return file_type::regular; +} +static uintmax_t get_file_size(const WIN32_FIND_DATAW& data) { + return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow; +} +static file_time_type get_write_time(const WIN32_FIND_DATAW& data) { + ULARGE_INTEGER tmp; + const FILETIME& time = data.ftLastWriteTime; + tmp.u.LowPart = time.dwLowDateTime; + tmp.u.HighPart = time.dwHighDateTime; + return file_time_type(file_time_type::duration(tmp.QuadPart)); +} + +#endif // !_LIBCPP_WIN32API } // namespace } // end namespace detail diff --git contrib/llvm-project/libcxx/src/iostream_init.h contrib/llvm-project/libcxx/src/iostream_init.h index b0a60f42a67c..7d1bb5c2d7d8 100644 --- contrib/llvm-project/libcxx/src/iostream_init.h +++ contrib/llvm-project/libcxx/src/iostream_init.h @@ -1,2 +1,2 @@ #pragma GCC system_header -_LIBCPP_HIDDEN ios_base::Init __start_std_streams _LIBCPP_INIT_PRIORITY_MAX; \ No newline at end of file +_LIBCPP_HIDDEN ios_base::Init __start_std_streams _LIBCPP_INIT_PRIORITY_MAX; diff --git contrib/llvm-project/libcxx/src/locale.cpp contrib/llvm-project/libcxx/src/locale.cpp index 79f03b85fab3..2234784769dd 100644 --- contrib/llvm-project/libcxx/src/locale.cpp +++ contrib/llvm-project/libcxx/src/locale.cpp @@ -898,7 +898,7 @@ ctype<wchar_t>::do_toupper(char_type c) const #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || defined(__MVS__) return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c; #else return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c; @@ -912,7 +912,7 @@ ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || defined(__MVS__) *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low] : *low; #else @@ -927,7 +927,7 @@ ctype<wchar_t>::do_tolower(char_type c) const #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || defined(__MVS__) return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c; #else return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c; @@ -941,7 +941,7 @@ ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || defined(__MVS__) *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low] : *low; #else @@ -1013,7 +1013,7 @@ ctype<char>::do_toupper(char_type c) const static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c; #elif defined(__NetBSD__) return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__) return isascii(c) ? static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c; #else @@ -1030,7 +1030,7 @@ ctype<char>::do_toupper(char_type* low, const char_type* high) const static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low; #elif defined(__NetBSD__) *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__) *low = isascii(*low) ? static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low; #else @@ -1047,7 +1047,7 @@ ctype<char>::do_tolower(char_type c) const static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c; #elif defined(__NetBSD__) return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__) return isascii(c) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c; #else @@ -1063,7 +1063,7 @@ ctype<char>::do_tolower(char_type* low, const char_type* high) const *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low; #elif defined(__NetBSD__) *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__) *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low; #else *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low; @@ -1211,6 +1211,12 @@ ctype<char>::classic_table() noexcept return _ctype_ + 1; #elif defined(_AIX) return (const unsigned int *)__lc_ctype_ptr->obj->mask; +#elif defined(__MVS__) +# if defined(__NATIVE_ASCII_F) + return const_cast<const ctype<char>::mask*> (__OBJ_DATA(__lc_ctype_a)->mask); +# else + return const_cast<const ctype<char>::mask*> (__ctypec); +# endif #else // Platform not supported: abort so the person doing the port knows what to // fix @@ -1259,7 +1265,26 @@ ctype<char>::__classic_upper_table() noexcept { return *__ctype_toupper_loc(); } -#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ +#elif defined(__MVS__) +const unsigned short* +ctype<char>::__classic_lower_table() _NOEXCEPT +{ +# if defined(__NATIVE_ASCII_F) + return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->lower); +# else + return const_cast<const unsigned short*>(__ctype + __TOLOWER_INDEX); +# endif +} +const unsigned short * +ctype<char>::__classic_upper_table() _NOEXCEPT +{ +# if defined(__NATIVE_ASCII_F) + return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->upper); +# else + return const_cast<const unsigned short*>(__ctype + __TOUPPER_INDEX); +# endif +} +#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__ // template <> class ctype_byname<char> diff --git contrib/llvm-project/libcxx/src/random.cpp contrib/llvm-project/libcxx/src/random.cpp index 286a45785154..6472a8dbcba3 100644 --- contrib/llvm-project/libcxx/src/random.cpp +++ contrib/llvm-project/libcxx/src/random.cpp @@ -36,6 +36,8 @@ # endif #elif defined(_LIBCPP_USING_NACL_RANDOM) # include <nacl/nacl_random.h> +#elif defined(_LIBCPP_USING_FUCHSIA_CPRNG) +# include <zircon/syscalls.h> #endif @@ -66,10 +68,8 @@ random_device::operator()() #elif defined(_LIBCPP_USING_ARC4_RANDOM) -random_device::random_device(const string& __token) +random_device::random_device(const string&) { - if (__token != "/dev/urandom") - __throw_system_error(ENOENT, ("random device not supported " + __token).c_str()); } random_device::~random_device() @@ -170,6 +170,27 @@ random_device::operator()() return r; } +#elif defined(_LIBCPP_USING_FUCHSIA_CPRNG) + +random_device::random_device(const string& __token) { + if (__token != "/dev/urandom") + __throw_system_error(ENOENT, ("random device not supported " + __token).c_str()); +} + +random_device::~random_device() {} + +unsigned random_device::operator()() { + // Implicitly link against the vDSO system call ABI without + // requiring the final link to specify -lzircon explicitly when + // statically linking libc++. +# pragma comment(lib, "zircon") + + // The system call cannot fail. It returns only when the bits are ready. + unsigned r; + _zx_cprng_draw(&r, sizeof(r)); + return r; +} + #else #error "Random device not implemented for this architecture" #endif @@ -189,7 +210,7 @@ random_device::entropy() const noexcept return std::numeric_limits<result_type>::digits; return ent; -#elif defined(__OpenBSD__) +#elif defined(__OpenBSD__) || defined(_LIBCPP_USING_FUCHSIA_CPRNG) return std::numeric_limits<result_type>::digits; #else return 0; diff --git contrib/llvm-project/libcxx/src/regex.cpp contrib/llvm-project/libcxx/src/regex.cpp index 425339a5c9b8..16ad8f0effdb 100644 --- contrib/llvm-project/libcxx/src/regex.cpp +++ contrib/llvm-project/libcxx/src/regex.cpp @@ -76,6 +76,125 @@ struct collationnames char char_; }; +#if defined(__MVS__) && !defined(__NATIVE_ASCII_F) +// EBCDIC IBM-1047 +// Sorted via the EBCDIC collating sequence +const collationnames collatenames[] = +{ + {"a", 0x81}, + {"alert", 0x2f}, + {"ampersand", 0x50}, + {"apostrophe", 0x7d}, + {"asterisk", 0x5c}, + {"b", 0x82}, + {"backslash", 0xe0}, + {"backspace", 0x16}, + {"c", 0x83}, + {"carriage-return", 0xd}, + {"circumflex", 0x5f}, + {"circumflex-accent", 0x5f}, + {"colon", 0x7a}, + {"comma", 0x6b}, + {"commercial-at", 0x7c}, + {"d", 0x84}, + {"dollar-sign", 0x5b}, + {"e", 0x85}, + {"eight", 0xf8}, + {"equals-sign", 0x7e}, + {"exclamation-mark", 0x5a}, + {"f", 0x86}, + {"five", 0xf5}, + {"form-feed", 0xc}, + {"four", 0xf4}, + {"full-stop", 0x4b}, + {"g", 0x87}, + {"grave-accent", 0x79}, + {"greater-than-sign", 0x6e}, + {"h", 0x88}, + {"hyphen", 0x60}, + {"hyphen-minus", 0x60}, + {"i", 0x89}, + {"j", 0x91}, + {"k", 0x92}, + {"l", 0x93}, + {"left-brace", 0xc0}, + {"left-curly-bracket", 0xc0}, + {"left-parenthesis", 0x4d}, + {"left-square-bracket", 0xad}, + {"less-than-sign", 0x4c}, + {"low-line", 0x6d}, + {"m", 0x94}, + {"n", 0x95}, + {"newline", 0x15}, + {"nine", 0xf9}, + {"number-sign", 0x7b}, + {"o", 0x96}, + {"one", 0xf1}, + {"p", 0x97}, + {"percent-sign", 0x6c}, + {"period", 0x4b}, + {"plus-sign", 0x4e}, + {"q", 0x98}, + {"question-mark", 0x6f}, + {"quotation-mark", 0x7f}, + {"r", 0x99}, + {"reverse-solidus", 0xe0}, + {"right-brace", 0xd0}, + {"right-curly-bracket", 0xd0}, + {"right-parenthesis", 0x5d}, + {"right-square-bracket", 0xbd}, + {"s", 0xa2}, + {"semicolon", 0x5e}, + {"seven", 0xf7}, + {"six", 0xf6}, + {"slash", 0x61}, + {"solidus", 0x61}, + {"space", 0x40}, + {"t", 0xa3}, + {"tab", 0x5}, + {"three", 0xf3}, + {"tilde", 0xa1}, + {"two", 0xf2}, + {"u", 0xa4}, + {"underscore", 0x6d}, + {"v", 0xa5}, + {"vertical-line", 0x4f}, + {"vertical-tab", 0xb}, + {"w", 0xa6}, + {"x", 0xa7}, + {"y", 0xa8}, + {"z", 0xa9}, + {"zero", 0xf0}, + {"A", 0xc1}, + {"B", 0xc2}, + {"C", 0xc3}, + {"D", 0xc4}, + {"E", 0xc5}, + {"F", 0xc6}, + {"G", 0xc7}, + {"H", 0xc8}, + {"I", 0xc9}, + {"J", 0xd1}, + {"K", 0xd2}, + {"L", 0xd3}, + {"M", 0xd4}, + {"N", 0xd5}, + {"NUL", 0}, + {"O", 0xd6}, + {"P", 0xd7}, + {"Q", 0xd8}, + {"R", 0xd9}, + {"S", 0xe2}, + {"T", 0xe3}, + {"U", 0xe4}, + {"V", 0xe5}, + {"W", 0xe6}, + {"X", 0xe7}, + {"Y", 0xe8}, + {"Z", 0xe9} +}; +#else +// ASCII const collationnames collatenames[] = { {"A", 0x41}, @@ -190,6 +309,7 @@ const collationnames collatenames[] = {"z", 0x7a}, {"zero", 0x30} }; +#endif struct classnames { diff --git contrib/llvm-project/libcxx/src/string.cpp contrib/llvm-project/libcxx/src/string.cpp index 608dcb2c5863..3c63f408240d 100644 --- contrib/llvm-project/libcxx/src/string.cpp +++ contrib/llvm-project/libcxx/src/string.cpp @@ -21,6 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD +#ifndef _LIBCPP_ABI_NO_BASIC_STRING_BASE_CLASS void __basic_string_common<true>::__throw_length_error() const { _VSTD::__throw_length_error("basic_string"); } @@ -28,6 +29,7 @@ void __basic_string_common<true>::__throw_length_error() const { void __basic_string_common<true>::__throw_out_of_range() const { _VSTD::__throw_out_of_range("basic_string"); } +#endif #define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__; #ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION diff --git contrib/llvm-project/libunwind/src/AddressSpace.hpp contrib/llvm-project/libunwind/src/AddressSpace.hpp index cfceac29537f..0c4dfeb4e683 100644 --- contrib/llvm-project/libunwind/src/AddressSpace.hpp +++ contrib/llvm-project/libunwind/src/AddressSpace.hpp @@ -121,23 +121,23 @@ struct UnwindInfoSections { uintptr_t dso_base; #endif #if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) - uintptr_t text_segment_length; + size_t text_segment_length; #endif #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) uintptr_t dwarf_section; - uintptr_t dwarf_section_length; + size_t dwarf_section_length; #endif #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) uintptr_t dwarf_index_section; - uintptr_t dwarf_index_section_length; + size_t dwarf_index_section_length; #endif #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) uintptr_t compact_unwind_section; - uintptr_t compact_unwind_section_length; + size_t compact_unwind_section_length; #endif #if defined(_LIBUNWIND_ARM_EHABI) uintptr_t arm_section; - uintptr_t arm_section_length; + size_t arm_section_length; #endif }; @@ -430,7 +430,7 @@ static bool checkForUnwindInfoSegment(const Elf_Phdr *phdr, size_t image_base, // .eh_frame_hdr records the start of .eh_frame, but not its size. // Rely on a zero terminator to find the end of the section. cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; - cbdata->sects->dwarf_section_length = UINTPTR_MAX; + cbdata->sects->dwarf_section_length = SIZE_MAX; return true; } } @@ -506,22 +506,22 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, info.dso_base = (uintptr_t)dyldInfo.mh; #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) info.dwarf_section = (uintptr_t)dyldInfo.dwarf_section; - info.dwarf_section_length = dyldInfo.dwarf_section_length; + info.dwarf_section_length = (size_t)dyldInfo.dwarf_section_length; #endif info.compact_unwind_section = (uintptr_t)dyldInfo.compact_unwind_section; - info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length; + info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length; return true; } #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) info.dso_base = 0; // Bare metal is statically linked, so no need to ask the dynamic loader - info.dwarf_section_length = (uintptr_t)(&__eh_frame_end - &__eh_frame_start); + info.dwarf_section_length = (size_t)(&__eh_frame_end - &__eh_frame_start); info.dwarf_section = (uintptr_t)(&__eh_frame_start); _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p", (void *)info.dwarf_section, (void *)info.dwarf_section_length); #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) info.dwarf_index_section = (uintptr_t)(&__eh_frame_hdr_start); - info.dwarf_index_section_length = (uintptr_t)(&__eh_frame_hdr_end - &__eh_frame_hdr_start); + info.dwarf_index_section_length = (size_t)(&__eh_frame_hdr_end - &__eh_frame_hdr_start); _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: index section %p length %p", (void *)info.dwarf_index_section, (void *)info.dwarf_index_section_length); #endif @@ -530,7 +530,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) // Bare metal is statically linked, so no need to ask the dynamic loader info.arm_section = (uintptr_t)(&__exidx_start); - info.arm_section_length = (uintptr_t)(&__exidx_end - &__exidx_start); + info.arm_section_length = (size_t)(&__exidx_end - &__exidx_start); _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p", (void *)info.arm_section, (void *)info.arm_section_length); if (info.arm_section && info.arm_section_length) @@ -584,7 +584,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, int length = 0; info.arm_section = (uintptr_t)dl_unwind_find_exidx((_Unwind_Ptr)targetAddr, &length); - info.arm_section_length = (uintptr_t)length * sizeof(EHABIIndexEntry); + info.arm_section_length = (size_t)length * sizeof(EHABIIndexEntry); if (info.arm_section && info.arm_section_length) return true; #elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) diff --git contrib/llvm-project/libunwind/src/DwarfParser.hpp contrib/llvm-project/libunwind/src/DwarfParser.hpp index 9515fb7dfd52..abf7f613a359 100644 --- contrib/llvm-project/libunwind/src/DwarfParser.hpp +++ contrib/llvm-project/libunwind/src/DwarfParser.hpp @@ -150,7 +150,7 @@ public: }; static bool findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, - uintptr_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo, + size_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo, CIE_Info *cieInfo); static const char *decodeFDE(A &addressSpace, pint_t fdeStart, FDE_Info *fdeInfo, CIE_Info *cieInfo, @@ -229,11 +229,11 @@ const char *CFI_Parser<A>::decodeFDE(A &addressSpace, pint_t fdeStart, /// Scan an eh_frame section to find an FDE for a pc template <typename A> bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, - uintptr_t sectionLength, pint_t fdeHint, + size_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo, CIE_Info *cieInfo) { //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc); pint_t p = (fdeHint != 0) ? fdeHint : ehSectionStart; - const pint_t ehSectionEnd = (sectionLength == UINTPTR_MAX) + const pint_t ehSectionEnd = (sectionLength == SIZE_MAX) ? static_cast<pint_t>(-1) : (ehSectionStart + sectionLength); while (p < ehSectionEnd) { diff --git contrib/llvm-project/lld/COFF/COFFLinkerContext.h contrib/llvm-project/lld/COFF/COFFLinkerContext.h index e5223da86ef8..a3a6f94a9413 100644 --- contrib/llvm-project/lld/COFF/COFFLinkerContext.h +++ contrib/llvm-project/lld/COFF/COFFLinkerContext.h @@ -15,12 +15,13 @@ #include "InputFiles.h" #include "SymbolTable.h" #include "Writer.h" +#include "lld/Common/CommonLinkerContext.h" #include "lld/Common/Timer.h" namespace lld { namespace coff { -class COFFLinkerContext { +class COFFLinkerContext : public CommonLinkerContext { public: COFFLinkerContext(); COFFLinkerContext(const COFFLinkerContext &) = delete; diff --git contrib/llvm-project/lld/COFF/Chunks.cpp contrib/llvm-project/lld/COFF/Chunks.cpp index 0bff11f450d1..6cabb22d98cf 100644 --- contrib/llvm-project/lld/COFF/Chunks.cpp +++ contrib/llvm-project/lld/COFF/Chunks.cpp @@ -12,7 +12,6 @@ #include "SymbolTable.h" #include "Symbols.h" #include "Writer.h" -#include "lld/Common/ErrorHandler.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/Object/COFF.h" @@ -430,7 +429,7 @@ void SectionChunk::sortRelocations() { return; warn("some relocations in " + file->getName() + " are not sorted"); MutableArrayRef<coff_relocation> newRelocs( - bAlloc.Allocate<coff_relocation>(relocsSize), relocsSize); + bAlloc().Allocate<coff_relocation>(relocsSize), relocsSize); memcpy(newRelocs.data(), relocsData, relocsSize * sizeof(coff_relocation)); llvm::sort(newRelocs, cmpByVa); setRelocs(newRelocs); @@ -635,7 +634,7 @@ void SectionChunk::printDiscardedMessage() const { // Removed by dead-stripping. If it's removed by ICF, ICF already // printed out the name, so don't repeat that here. if (sym && this == repl) - message("Discarded " + sym->getName()); + log("Discarded " + sym->getName()); } StringRef SectionChunk::getDebugName() const { diff --git contrib/llvm-project/lld/COFF/Config.h contrib/llvm-project/lld/COFF/Config.h index 3917975e165d..4bb42c88aa93 100644 --- contrib/llvm-project/lld/COFF/Config.h +++ contrib/llvm-project/lld/COFF/Config.h @@ -43,6 +43,7 @@ static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386; struct Export { StringRef name; // N in /export:N or /export:E=N StringRef extName; // E in /export:E=N + StringRef aliasTarget; // GNU specific: N in "alias == N" Symbol *sym = nullptr; uint16_t ordinal = 0; bool noname = false; @@ -63,6 +64,7 @@ struct Export { bool operator==(const Export &e) { return (name == e.name && extName == e.extName && + aliasTarget == e.aliasTarget && ordinal == e.ordinal && noname == e.noname && data == e.data && isPrivate == e.isPrivate); } @@ -282,7 +284,7 @@ struct Configuration { bool stdcallFixup = false; }; -extern Configuration *config; +extern std::unique_ptr<Configuration> config; } // namespace coff } // namespace lld diff --git contrib/llvm-project/lld/COFF/DLL.cpp contrib/llvm-project/lld/COFF/DLL.cpp index 6fec9df5617d..bfa2a6910e2b 100644 --- contrib/llvm-project/lld/COFF/DLL.cpp +++ contrib/llvm-project/lld/COFF/DLL.cpp @@ -659,14 +659,14 @@ void DelayLoadContents::create(COFFLinkerContext &ctx, Defined *h) { // Add a syntentic symbol for this load thunk, using the "__imp_load" // prefix, in case this thunk needs to be added to the list of valid // call targets for Control Flow Guard. - StringRef symName = saver.save("__imp_load_" + extName); + StringRef symName = saver().save("__imp_load_" + extName); s->loadThunkSym = cast<DefinedSynthetic>(ctx.symtab.addSynthetic(symName, t)); } } thunks.push_back(tm); StringRef tmName = - saver.save("__tailMerge_" + syms[0]->getDLLName().lower()); + saver().save("__tailMerge_" + syms[0]->getDLLName().lower()); ctx.symtab.addSynthetic(tmName, tm); // Terminate with null values. addresses.push_back(make<NullChunk>(8)); diff --git contrib/llvm-project/lld/COFF/Driver.cpp contrib/llvm-project/lld/COFF/Driver.cpp index 07b60673577e..1546291e16c6 100644 --- contrib/llvm-project/lld/COFF/Driver.cpp +++ contrib/llvm-project/lld/COFF/Driver.cpp @@ -19,9 +19,7 @@ #include "Writer.h" #include "lld/Common/Args.h" #include "lld/Common/Driver.h" -#include "lld/Common/ErrorHandler.h" #include "lld/Common/Filesystem.h" -#include "lld/Common/Memory.h" #include "lld/Common/Timer.h" #include "lld/Common/Version.h" #include "llvm/ADT/Optional.h" @@ -60,39 +58,25 @@ using namespace llvm::sys; namespace lld { namespace coff { -Configuration *config; -LinkerDriver *driver; +std::unique_ptr<Configuration> config; +std::unique_ptr<LinkerDriver> driver; -bool link(ArrayRef<const char *> args, bool canExitEarly, raw_ostream &stdoutOS, - raw_ostream &stderrOS) { - lld::stdoutOS = &stdoutOS; - lld::stderrOS = &stderrOS; +bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, + llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput) { + // This driver-specific context will be freed later by lldMain(). + auto *ctx = new COFFLinkerContext; - errorHandler().cleanupCallback = []() { - freeArena(); - }; - - errorHandler().logName = args::getFilenameWithoutExe(args[0]); - errorHandler().errorLimitExceededMsg = - "too many errors emitted, stopping now" - " (use /errorlimit:0 to see all errors)"; - errorHandler().exitEarly = canExitEarly; - stderrOS.enable_colors(stderrOS.has_colors()); + ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput); + ctx->e.logName = args::getFilenameWithoutExe(args[0]); + ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now" + " (use /errorlimit:0 to see all errors)"; - COFFLinkerContext ctx; - config = make<Configuration>(); - driver = make<LinkerDriver>(ctx); + config = std::make_unique<Configuration>(); + driver = std::make_unique<LinkerDriver>(*ctx); driver->linkerMain(args); - // Call exit() if we can to avoid calling destructors. - if (canExitEarly) - exitLld(errorCount() ? 1 : 0); - - bool ret = errorCount() == 0; - if (!canExitEarly) - errorHandler().reset(); - return ret; + return errorCount() == 0; } // Parse options of the form "old;new". @@ -162,7 +146,7 @@ static std::future<MBErrPair> createFutureForFile(std::string path) { static StringRef mangle(StringRef sym) { assert(config->machine != IMAGE_FILE_MACHINE_UNKNOWN); if (config->machine == I386) - return saver.save("_" + sym); + return saver().save("_" + sym); return sym; } @@ -208,17 +192,11 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb, ctx.symtab.addFile(make<ArchiveFile>(ctx, mbref)); break; case file_magic::bitcode: - if (lazy) - ctx.symtab.addFile(make<LazyObjFile>(ctx, mbref)); - else - ctx.symtab.addFile(make<BitcodeFile>(ctx, mbref, "", 0)); + ctx.symtab.addFile(make<BitcodeFile>(ctx, mbref, "", 0, lazy)); break; case file_magic::coff_object: case file_magic::coff_import_library: - if (lazy) - ctx.symtab.addFile(make<LazyObjFile>(ctx, mbref)); - else - ctx.symtab.addFile(make<ObjFile>(ctx, mbref)); + ctx.symtab.addFile(make<ObjFile>(ctx, mbref, lazy)); break; case file_magic::pdb: ctx.symtab.addFile(make<PDBInputFile>(ctx, mbref)); @@ -282,7 +260,8 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName, if (magic == file_magic::coff_object) { obj = make<ObjFile>(ctx, mb); } else if (magic == file_magic::bitcode) { - obj = make<BitcodeFile>(ctx, mb, parentName, offsetInArchive); + obj = + make<BitcodeFile>(ctx, mb, parentName, offsetInArchive, /*lazy=*/false); } else { error("unknown file type: " + mb.getBufferIdentifier()); return; @@ -363,9 +342,9 @@ void LinkerDriver::parseDirectives(InputFile *file) { Export exp = parseExport(e); if (config->machine == I386 && config->mingw) { if (!isDecorated(exp.name)) - exp.name = saver.save("_" + exp.name); + exp.name = saver().save("_" + exp.name); if (!exp.extName.empty() && !isDecorated(exp.extName)) - exp.extName = saver.save("_" + exp.extName); + exp.extName = saver().save("_" + exp.extName); } exp.directives = true; config->exports.push_back(exp); @@ -447,11 +426,11 @@ StringRef LinkerDriver::doFindFile(StringRef filename) { SmallString<128> path = dir; sys::path::append(path, filename); if (sys::fs::exists(path.str())) - return saver.save(path.str()); + return saver().save(path.str()); if (!hasExt) { path.append(".obj"); if (sys::fs::exists(path.str())) - return saver.save(path.str()); + return saver().save(path.str()); } } return filename; @@ -488,7 +467,7 @@ StringRef LinkerDriver::doFindLibMinGW(StringRef filename) { SmallString<128> s = filename; sys::path::replace_extension(s, ".a"); - StringRef libName = saver.save("lib" + s.str()); + StringRef libName = saver().save("lib" + s.str()); return doFindFile(libName); } @@ -497,7 +476,7 @@ StringRef LinkerDriver::doFindLib(StringRef filename) { // Add ".lib" to Filename if that has no file extension. bool hasExt = filename.contains('.'); if (!hasExt) - filename = saver.save(filename + ".lib"); + filename = saver().save(filename + ".lib"); StringRef ret = doFindFile(filename); // For MinGW, if the find above didn't turn up anything, try // looking for a MinGW formatted library name. @@ -530,7 +509,7 @@ void LinkerDriver::addLibSearchPaths() { Optional<std::string> envOpt = Process::GetEnv("LIB"); if (!envOpt.hasValue()) return; - StringRef env = saver.save(*envOpt); + StringRef env = saver().save(*envOpt); while (!env.empty()) { StringRef path; std::tie(path, env) = env.split(';'); @@ -815,6 +794,7 @@ static void createImportLibrary(bool asLib) { e2.Name = std::string(e1.name); e2.SymbolName = std::string(e1.symbolName); e2.ExtName = std::string(e1.extName); + e2.AliasTarget = std::string(e1.aliasTarget); e2.Ordinal = e1.ordinal; e2.Noname = e1.noname; e2.Data = e1.data; @@ -877,8 +857,8 @@ static void parseModuleDefs(StringRef path) { driver->takeBuffer(std::move(mb)); if (config->outputFile.empty()) - config->outputFile = std::string(saver.save(m.OutputFile)); - config->importName = std::string(saver.save(m.ImportName)); + config->outputFile = std::string(saver().save(m.OutputFile)); + config->importName = std::string(saver().save(m.ImportName)); if (m.ImageBase) config->imageBase = m.ImageBase; if (m.StackReserve) @@ -906,13 +886,14 @@ static void parseModuleDefs(StringRef path) { // DLL instead. This is supported by both MS and GNU linkers. if (!e1.ExtName.empty() && e1.ExtName != e1.Name && StringRef(e1.Name).contains('.')) { - e2.name = saver.save(e1.ExtName); - e2.forwardTo = saver.save(e1.Name); + e2.name = saver().save(e1.ExtName); + e2.forwardTo = saver().save(e1.Name); config->exports.push_back(e2); continue; } - e2.name = saver.save(e1.Name); - e2.extName = saver.save(e1.ExtName); + e2.name = saver().save(e1.Name); + e2.extName = saver().save(e1.ExtName); + e2.aliasTarget = saver().save(e1.AliasTarget); e2.ordinal = e1.Ordinal; e2.noname = e1.Noname; e2.data = e1.Data; @@ -1909,9 +1890,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) { Export e = parseExport(arg->getValue()); if (config->machine == I386) { if (!isDecorated(e.name)) - e.name = saver.save("_" + e.name); + e.name = saver().save("_" + e.name); if (!e.extName.empty() && !isDecorated(e.extName)) - e.extName = saver.save("_" + e.extName); + e.extName = saver().save("_" + e.extName); } config->exports.push_back(e); } ########## TRUNCATED ###########