diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-01-27 22:17:16 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-05-14 11:44:34 +0000 |
commit | 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623 (patch) | |
tree | 2a5d3b2fe5c852e91531d128d9177754572d5338 /contrib/llvm-project/clang | |
parent | 0eae32dcef82f6f06de6419a0d623d7def0cc8f6 (diff) | |
parent | 6f8fc217eaa12bf657be1c6468ed9938d10168b3 (diff) | |
download | src-04eeddc0aa8e0a417a16eaf9d7d095207f4a8623.tar.gz src-04eeddc0aa8e0a417a16eaf9d7d095207f4a8623.zip |
Diffstat (limited to 'contrib/llvm-project/clang')
502 files changed, 10320 insertions, 4923 deletions
diff --git a/contrib/llvm-project/clang/include/clang/APINotes/Types.h b/contrib/llvm-project/clang/include/clang/APINotes/Types.h index 0d97e9ad8623..f741d9b91d76 100644 --- a/contrib/llvm-project/clang/include/clang/APINotes/Types.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h b/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h index aba18b060b02..25e00860060f 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/ASTContext.h b/contrib/llvm-project/clang/include/clang/AST/ASTContext.h index 63f2c948c79b..f39ce14bc82c 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ASTContext.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h b/contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h index 918c2b9e350c..2dbc44c5dcd4 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h +++ b/contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h @@ -21,7 +21,6 @@ namespace clang { -class ASTContext; class NamedDecl; class DeclContext; diff --git a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h index 442039044cfe..b2fc2d2c7e4b 100644 --- a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h index 75aef734ba9b..41772ba0f63c 100644 --- a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h b/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h index 9fea7b26f678..c9162b1779bc 100644 --- a/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h b/contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h index a63cb0be099d..62006ef0f26e 100644 --- a/contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/Attr.h b/contrib/llvm-project/clang/include/clang/AST/Attr.h index 6366d6e8837e..070e160d6517 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Attr.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/AttrIterator.h b/contrib/llvm-project/clang/include/clang/AST/AttrIterator.h index 78ce9314a2bb..66571e1cf0b8 100644 --- a/contrib/llvm-project/clang/include/clang/AST/AttrIterator.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def index 9b270682f8cf..cdf0804680ad 100644 --- a/contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/Comment.h b/contrib/llvm-project/clang/include/clang/AST/Comment.h index 4184e103206d..5ecc35791b7b 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Comment.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/CommentLexer.h b/contrib/llvm-project/clang/include/clang/AST/CommentLexer.h index 94f778501e75..9aa1681cb2c5 100644 --- a/contrib/llvm-project/clang/include/clang/AST/CommentLexer.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h b/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h index 8db09e6b57d0..cb545aff51f8 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h b/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h index 34df8ce1309e..4f8343efad16 100644 --- a/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/Decl.h b/contrib/llvm-project/clang/include/clang/AST/Decl.h index 2c92571325c8..5ebd7e5d0d36 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Decl.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h index 2a0a19597391..06d2f17d1430 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h b/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h index cc7bfc86a521..2833df0505da 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h b/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h index 9899fc29b82d..903cdb7bfcc8 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h b/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h index 79ec1d6e5c3c..110b7dc0c6f2 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h b/contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h index 5f03bce6e9a8..42c97204a613 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h index f7a2e3146d06..d216b359816e 100755 --- a/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h b/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h index 38da6fc727fb..0762e0a478ea 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/Expr.h b/contrib/llvm-project/clang/include/clang/AST/Expr.h index 54ad1934e477..ce5280d77c36 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Expr.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h b/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h index 1544c498ef66..6849b65b71c0 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h b/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h index b0f057dbaa02..3b7ad8662ad9 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/FormatString.h b/contrib/llvm-project/clang/include/clang/AST/FormatString.h index 8c944451f796..d7933382f13d 100644 --- a/contrib/llvm-project/clang/include/clang/AST/FormatString.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h b/contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h index e42f0449f6db..054220b8a32c 100644 --- a/contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/LocInfoType.h b/contrib/llvm-project/clang/include/clang/AST/LocInfoType.h index 7e845ad03587..876c7deeceb9 100644 --- a/contrib/llvm-project/clang/include/clang/AST/LocInfoType.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h b/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h index eb33759682d6..a4a6ce4c2708 100644 --- a/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h b/contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h index c95516538ad1..cf320c8a478a 100644 --- a/contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/OSLog.h b/contrib/llvm-project/clang/include/clang/AST/OSLog.h index c24e79ce6da0..3772597e2616 100644 --- a/contrib/llvm-project/clang/include/clang/AST/OSLog.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h b/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h index 3fd1b6d30080..3ecc1d40fafc 100644 --- a/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h b/contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h index 899bbcb3be45..82df031d4126 100644 --- a/contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h b/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h index f6816e938f2a..fd40328d8dcf 100644 --- a/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h b/contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h index 8313e0441be5..daa86cda2d99 100644 --- a/contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h b/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h index fa27a12cfbb9..e8064121d279 100644 --- a/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/TemplateName.h b/contrib/llvm-project/clang/include/clang/AST/TemplateName.h index 2befb5c1b45e..44080a7f56d4 100644 --- a/contrib/llvm-project/clang/include/clang/AST/TemplateName.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h b/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h index 7a036836e8c4..8cfa579a22da 100644 --- a/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h +++ b/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 a/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h b/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h index c75aa0785a63..17b47f6ab96b 100644 --- a/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h +++ b/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 a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h index 55cce324b436..86bd44091b59 100644 --- a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/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 a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h index 10625311c1a5..3f6f364d6505 100644 --- a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h +++ b/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 a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Parser.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Parser.h index af370d83782a..26e321c98ff6 100644 --- a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Parser.h +++ b/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 a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Registry.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Registry.h index f91f5fe01c4e..ee47469c6e18 100644 --- a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Registry.h +++ b/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 a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h index 5b3f8a7ca5eb..e1c19eb835ba 100644 --- a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h index a0c767bf92d2..6d78fa4a897a 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/Consumed.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/Consumed.h index dec1ae3b2b4b..24702567ab6c 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/Consumed.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index a0ae44131b45..2f6a78126a1d 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h index e3b6e61d3026..088474b9b298 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h b/contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h index 846ff7719ce1..6e5e019ce263 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/BodyFarm.h b/contrib/llvm-project/clang/include/clang/Analysis/BodyFarm.h index 72607f8839f5..d947ac070209 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/BodyFarm.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/CFG.h b/contrib/llvm-project/clang/include/clang/Analysis/CFG.h index b8e453fcc235..c5512a7e1499 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/CFG.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/CloneDetection.h b/contrib/llvm-project/clang/include/clang/Analysis/CloneDetection.h index 0b86c7fd86dd..b2911a5b44eb 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/CloneDetection.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h new file mode 100644 index 000000000000..e6ceb3a89131 --- /dev/null +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h index a5d4a5d6ba40..f327abe63751 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h new file mode 100644 index 000000000000..5c1b41d53892 --- /dev/null +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index 4a3c0239f8e1..e560305cf5ca 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h index 52d84eb13c56..e926adf6f0b2 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/MapLattice.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/MapLattice.h new file mode 100644 index 000000000000..ff403f68b7c5 --- /dev/null +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h new file mode 100644 index 000000000000..5532813d6d29 --- /dev/null +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h new file mode 100644 index 000000000000..a12674a173be --- /dev/null +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h index 6193b9860d33..9f44475b14ba 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h new file mode 100644 index 000000000000..da04f926c597 --- /dev/null +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/IssueHash.h b/contrib/llvm-project/clang/include/clang/Analysis/IssueHash.h index 9c02b79f58f9..78bebbdb6ec7 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/IssueHash.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h b/contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h index 235d26083191..446f67b23e75 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/ProgramPoint.h b/contrib/llvm-project/clang/include/clang/Analysis/ProgramPoint.h index 546224bfd58d..680713a52f2f 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/ProgramPoint.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/RetainSummaryManager.h b/contrib/llvm-project/clang/include/clang/Analysis/RetainSummaryManager.h index b7ccb0317830..d9a0416e1ce5 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/RetainSummaryManager.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h b/contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h index d26e9159a937..278f20e87cc6 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h b/contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h index ab9f19da5d59..c1187b81420b 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/Attr.td b/contrib/llvm-project/clang/include/clang/Basic/Attr.td index 10c5c7f1b879..be56373cc3ca 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Attr.td +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td b/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td index 8a7424a88c9f..18fac924b114 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h b/contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h index 010cefcaf340..4a4c1a883cf4 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/Builtins.def b/contrib/llvm-project/clang/include/clang/Basic/Builtins.def index 45d445163749..d2cb14d2fd8c 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Builtins.def +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def index 025fef05c8e0..6b94dd857300 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def index 06560415e686..495a036e576f 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def index bc6208be4560..0669a96b942b 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def index 723302f108e2..0da875525c0c 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h index 33ec03a17136..5a5c2689c689 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h b/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h index 918dc7c8becc..df16827debfc 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td b/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td index ab2c738a2ace..c932c9057278 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticAST.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticAST.h index 76c31ad9508e..24ef2689eac0 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticAST.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td index d788c8517914..a89bdff1a10c 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysis.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysis.h index f9037cc8d75a..676b58f7d6ef 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysis.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticComment.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticComment.h index 6e011bfcebab..17c0053e9a33 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticComment.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTU.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTU.h index ded85ec3f840..4341bf327b69 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTU.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriver.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriver.h index cecd8fd6b4d5..6931bd46542e 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriver.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td index a7fd2f26478c..e635be6b6d1b 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h index 430da6f724ed..76d893a5ccf8 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontend.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontend.h index f57c587fb469..ab4e855f2de0 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontend.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td index c0642efaee4e..608e16147b1c 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h index 375930c14848..ba5f5acc8ce6 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticLex.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticLex.h index 7a3128de3b82..5f237085ae03 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticLex.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParse.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParse.h index d066d3f71a25..81a8185d25fb 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParse.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td index 9dc036c03faa..770ddb3ab16f 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticRefactoring.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticRefactoring.h index fc7564047a24..9b628dbeb7c2 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticRefactoring.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSema.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSema.h index 7323167aeee8..45014fe21271 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSema.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td index f2089bfda04d..a8cf00c1263f 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerialization.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerialization.h index b3d99fb3feaa..0c622a565773 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerialization.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h b/contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h index edb8031a20b8..ac8e790230fc 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h b/contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h index 19c967efcc42..aaf1297c1a64 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/LangOptions.h b/contrib/llvm-project/clang/include/clang/Basic/LangOptions.h index 35b33c2e0971..09afa641acf9 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/LangOptions.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h b/contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h index d6cb1a210519..512bcb1e6ef1 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/OperatorPrecedence.h b/contrib/llvm-project/clang/include/clang/Basic/OperatorPrecedence.h index 61ac7ad62f6b..9bda3eb28fdf 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/OperatorPrecedence.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h b/contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h index 9fb70bff7fee..ddee6821e2e1 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/PragmaKinds.h b/contrib/llvm-project/clang/include/clang/Basic/PragmaKinds.h index 82c0d5f0a551..176bbc9ac7ca 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/PragmaKinds.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/ProfileList.h b/contrib/llvm-project/clang/include/clang/Basic/ProfileList.h index 989c36549a3d..aa472f126818 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/ProfileList.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def b/contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def index f6ef62a64636..1d4024dfb20d 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/TargetID.h b/contrib/llvm-project/clang/include/clang/Basic/TargetID.h index 1a9785574d06..2579276fc034 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/TargetID.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h b/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h index 437feba85e23..686a365b8c12 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/arm_neon.td b/contrib/llvm-project/clang/include/clang/Basic/arm_neon.td index 173003d171ee..2e9798129fdf 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/arm_neon.td +++ b/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 a/contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td b/contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td index cc242da7f1ca..6451e77e77f6 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td +++ b/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 a/contrib/llvm-project/clang/include/clang/CodeGen/CodeGenABITypes.h b/contrib/llvm-project/clang/include/clang/CodeGen/CodeGenABITypes.h index 3c745fadbe78..fda0855dc868 100644 --- a/contrib/llvm-project/clang/include/clang/CodeGen/CodeGenABITypes.h +++ b/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 a/contrib/llvm-project/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/contrib/llvm-project/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h index 8821cd70362e..c13e052149d9 100644 --- a/contrib/llvm-project/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h +++ b/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 a/contrib/llvm-project/clang/include/clang/CodeGen/SwiftCallingConv.h b/contrib/llvm-project/clang/include/clang/CodeGen/SwiftCallingConv.h index b1a638a58a09..d7a0c84699ab 100644 --- a/contrib/llvm-project/clang/include/clang/CodeGen/SwiftCallingConv.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Driver/Options.td b/contrib/llvm-project/clang/include/clang/Driver/Options.td index dc8bd831f2a2..b3de12e8c7b5 100644 --- a/contrib/llvm-project/clang/include/clang/Driver/Options.td +++ b/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 a/contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h b/contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h index 84bb324775d1..d288b0151c9f 100644 --- a/contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h b/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h index 4afc9bf36b5f..329833bb13be 100644 --- a/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Driver/Types.def b/contrib/llvm-project/clang/include/clang/Driver/Types.def index 997eea445c22..7adf59ca5c99 100644 --- a/contrib/llvm-project/clang/include/clang/Driver/Types.def +++ b/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 a/contrib/llvm-project/clang/include/clang/Driver/Util.h b/contrib/llvm-project/clang/include/clang/Driver/Util.h index 6788420912a1..92d3d40433a3 100644 --- a/contrib/llvm-project/clang/include/clang/Driver/Util.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Format/Format.h b/contrib/llvm-project/clang/include/clang/Format/Format.h index 0f97e80d425e..326e85305c8e 100755 --- a/contrib/llvm-project/clang/include/clang/Format/Format.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Frontend/ASTConsumers.h b/contrib/llvm-project/clang/include/clang/Frontend/ASTConsumers.h index 98cfc7cadc0d..0e068bf5cccb 100644 --- a/contrib/llvm-project/clang/include/clang/Frontend/ASTConsumers.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h b/contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h index 74e152ea5952..577daad86b20 100644 --- a/contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Frontend/FrontendActions.h b/contrib/llvm-project/clang/include/clang/Frontend/FrontendActions.h index 545a7e842c4f..8eceb81723d2 100644 --- a/contrib/llvm-project/clang/include/clang/Frontend/FrontendActions.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h b/contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h index 1d9d89a28c6c..7ce8076a3ee4 100644 --- a/contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Frontend/PCHContainerOperations.h b/contrib/llvm-project/clang/include/clang/Frontend/PCHContainerOperations.h index fa977a63f32e..098d32ec3869 100644 --- a/contrib/llvm-project/clang/include/clang/Frontend/PCHContainerOperations.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h b/contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h index dacbffef0b12..628736f34091 100644 --- a/contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h b/contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h index 58954dc6bafa..5586ef65e393 100644 --- a/contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnostics.h b/contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnostics.h index 4e67fd13ac5b..6464693c1482 100644 --- a/contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnostics.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Frontend/Utils.h b/contrib/llvm-project/clang/include/clang/Frontend/Utils.h index da2d79af2eba..a05584bfe551 100644 --- a/contrib/llvm-project/clang/include/clang/Frontend/Utils.h +++ b/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 a/contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h b/contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h index 20cf8fbdad96..eb66e725000c 100644 --- a/contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h b/contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h index 2dc0fd5963a2..721a649deb43 100644 --- a/contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h b/contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h index 121ca893e314..56025c8a3ed5 100644 --- a/contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h b/contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h index b3445703f782..74768717470b 100644 --- a/contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h b/contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h index ea96bb12bec6..e567f6391531 100644 --- a/contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h b/contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h index 1a0d5ed57b28..49687cb5cc85 100644 --- a/contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Parse/Parser.h b/contrib/llvm-project/clang/include/clang/Parse/Parser.h index 741a484390b2..74010ca66f99 100644 --- a/contrib/llvm-project/clang/include/clang/Parse/Parser.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Parse/RAIIObjectsForParser.h b/contrib/llvm-project/clang/include/clang/Parse/RAIIObjectsForParser.h index bc1754614ad9..8e6e03685c50 100644 --- a/contrib/llvm-project/clang/include/clang/Parse/RAIIObjectsForParser.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h b/contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h index 49b69c585ff7..13a88bb9f896 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/CleanupInfo.h b/contrib/llvm-project/clang/include/clang/Sema/CleanupInfo.h index ea9df49f77e1..45d16fea93e0 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/CleanupInfo.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/CodeCompleteConsumer.h b/contrib/llvm-project/clang/include/clang/Sema/CodeCompleteConsumer.h index 6b37e3c50dba..41c495882b27 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h b/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h index 2704a9c1fc78..2437be497de4 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/ExternalSemaSource.h b/contrib/llvm-project/clang/include/clang/Sema/ExternalSemaSource.h index 9c18aa1398d3..17a7ffd3bb68 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/ExternalSemaSource.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/Initialization.h b/contrib/llvm-project/clang/include/clang/Sema/Initialization.h index 679e12ee22d4..21adc9fa2ac0 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/Initialization.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/Overload.h b/contrib/llvm-project/clang/include/clang/Sema/Overload.h index 88405a63b735..48997e186ef6 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/Overload.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h b/contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h index 6403179cb327..4fa6f09d3321 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/ParsedTemplate.h b/contrib/llvm-project/clang/include/clang/Sema/ParsedTemplate.h index f0245b93c7eb..926cec2c547c 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/ParsedTemplate.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h b/contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h index ccd15ea6a818..08bf53d22f8a 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/Sema.h b/contrib/llvm-project/clang/include/clang/Sema/Sema.h index 79834554a50d..4b609f4b1477 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/Sema.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h b/contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h index dc5f0ec97e85..b73a152533d1 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Sema/TemplateInstCallback.h b/contrib/llvm-project/clang/include/clang/Sema/TemplateInstCallback.h index 3ab0e8c6be9f..9258a7f41ac1 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/TemplateInstCallback.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h index 341da5bd1d62..f98e173b158c 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h index f24ccf579aa8..d46a6c4500f4 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h index 978f6d86ea5c..e455e4d4d96a 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h b/contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h index 5f4812626224..9d6b52a97f52 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h b/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h index 3e84a65c4b80..2168ce2ce607 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h b/contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h index 7081eedad4b4..4305bae5ee95 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h b/contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h index 33fc4a0a24e0..9f9700a418a9 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h index e2be957821b9..bdfe3901c5b8 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h index bbc5111ccacc..6243bbd5d53b 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def index c0cade46d614..7b976ddeaba2 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 3c93ebeccde8..9ec5bcc87554 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h index 49ab25eca2dd..558881176327 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index d2f71baa56a4..7e45d24e5695 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h index 71a590d9e9a2..2694aac478cd 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h +++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h @@ -20,7 +20,6 @@ namespace clang { -class AnalyzerOptions; class MacroExpansionContext; class Preprocessor; diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index bb598af68166..8a778389bcbe 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index d135e70dd75d..bfaeb06951d7 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index a383012dc351..94fa0d9ecdc3 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h index a81d67ab3063..e89a993ca8d2 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h index 6d2b495dc0f5..3ff453a8de4f 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index cef7dda172f3..feb4a72fe8d0 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h index 53b221cb53c9..eb2b0b343428 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index 9a34639e2707..3204ac460ed0 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h index 3a0bec9d04e5..6c487697bc55 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index 61dfdbb0688b..1df47dae25bf 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index 6199c8d8d179..f4b229070d67 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h index bcc29a60ad70..f3b1c1f20645 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h index 2b12330e4f2d..31b1c245200e 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ b/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 a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h index 5f9ae78dac63..7b7087622bc2 100644 --- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiff.h b/contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiff.h index c772ad84c139..5fe6db6cb133 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiff.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h b/contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h index 1e784ef43ac1..b74af5e8f24f 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/CommonOptionsParser.h b/contrib/llvm-project/clang/include/clang/Tooling/CommonOptionsParser.h index 0f072c2886ab..3c0480af3779 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/CommonOptionsParser.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/CompilationDatabase.h b/contrib/llvm-project/clang/include/clang/Tooling/CompilationDatabase.h index 90af15536961..fee584acb486 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/CompilationDatabase.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h index 7d0b8f2138f9..7c830d3f2733 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h index d58e736ab6a6..5c6dce611a95 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h index 9e2ff82f5614..2eb7a35b27b9 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h index 0f3a5369a021..b7631c09f275 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h index e61147d6f2b0..d1a7aab8c24b 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/FixIt.h b/contrib/llvm-project/clang/include/clang/Tooling/FixIt.h index 5fce71f2d8f7..1624c2d6be36 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/FixIt.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h index 239be36012c3..33dd386d2340 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/AtomicChange.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/AtomicChange.h index f1034a3d0579..3945a7c9fefb 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/AtomicChange.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/Extract.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/Extract.h index 930991328ca0..2f7c5bc9acff 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/Extract.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h index 034a0aaaf6db..be44518d4bce 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Lookup.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Lookup.h index 448bc422c4e7..dcb40b7eee66 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Lookup.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h index 63d46abc2034..6fb2decf8614 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringAction.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringAction.h index d4294ddb2f66..b362f655965e 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringAction.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRule.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRule.h index 57dffa945acc..388535a69b8b 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRule.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h index 6a6dd83731e9..49e4a0c149f1 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRules.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRules.h index e9606fd6018e..86fcc6ad0a79 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRules.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h index fb373fcf5029..e6ebaea5248a 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOption.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOption.h index 659e02b48e5c..b022c5d61b03 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOption.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h index d58b11355a26..f9f85f6eeb82 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h index 84122b111ee1..1575a136b11c 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h index 2035c02bc17a..016eff80ca7b 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringRuleContext.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringRuleContext.h index e0da9469deb5..7d97f811f024 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringRuleContext.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/RenamingAction.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/RenamingAction.h index b04bc3e2d202..43a8d56e4e71 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/RenamingAction.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolName.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolName.h index 9131a4565da7..6c28d40f3679 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolName.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h index c4bfaa9cc377..0ae023b8d4e4 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFinder.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFinder.h index 30f7f0a0008c..a7ffa8556888 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFinder.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h index 726987d9d46a..e81b5c2345c9 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h index 7a7dd76c4238..c3ffb4421e00 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/ReplacementsYaml.h b/contrib/llvm-project/clang/include/clang/Tooling/ReplacementsYaml.h index 83e35d623255..838f87fd1978 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/ReplacementsYaml.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/BuildTree.h b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/BuildTree.h index 3c8dd8ceed09..d6235797fd7a 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/BuildTree.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tree.h b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tree.h index b92e92305417..2063c6b7d82a 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tree.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Tooling.h b/contrib/llvm-project/clang/include/clang/Tooling/Tooling.h index c9c6a2ffb7b3..b36f58ad3046 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Tooling.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/MatchConsumer.h b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/MatchConsumer.h index cb0a5f684b7d..fb57dabb0a6f 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/MatchConsumer.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/Parsing.h b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/Parsing.h index b143f63d8ca8..177eca6a044d 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/Parsing.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/RangeSelector.h b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/RangeSelector.h index 38ec24efec65..1e288043f0a8 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/RangeSelector.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/RewriteRule.h b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/RewriteRule.h index ac93db8446df..6b14861e92d7 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/RewriteRule.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCode.h b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCode.h index 2c7eb65371cf..16411b9c398d 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCode.h +++ b/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 a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCodeBuilders.h b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCodeBuilders.h index 6c79a7588f28..ab0eb71ef44e 100644 --- a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCodeBuilders.h +++ b/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 a/contrib/llvm-project/clang/lib/ARCMigrate/Internals.h b/contrib/llvm-project/clang/lib/ARCMigrate/Internals.h index ed0136e4867a..8b482738cc89 100644 --- a/contrib/llvm-project/clang/lib/ARCMigrate/Internals.h +++ b/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 a/contrib/llvm-project/clang/lib/ARCMigrate/TransAutoreleasePool.cpp b/contrib/llvm-project/clang/lib/ARCMigrate/TransAutoreleasePool.cpp index 393adcd85a3f..47587d81850a 100644 --- a/contrib/llvm-project/clang/lib/ARCMigrate/TransAutoreleasePool.cpp +++ b/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 a/contrib/llvm-project/clang/lib/ARCMigrate/Transforms.cpp b/contrib/llvm-project/clang/lib/ARCMigrate/Transforms.cpp index ca48160d9c85..a08b0d084bb6 100644 --- a/contrib/llvm-project/clang/lib/ARCMigrate/Transforms.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/ASTContext.cpp b/contrib/llvm-project/clang/lib/AST/ASTContext.cpp index 701260881a93..a1d5673950e1 100644 --- a/contrib/llvm-project/clang/lib/AST/ASTContext.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp b/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp index 7f78da10e0b3..457465e87d93 100644 --- a/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/AttrImpl.cpp b/contrib/llvm-project/clang/lib/AST/AttrImpl.cpp index c2f13cf63830..7b8acfcd92be 100644 --- a/contrib/llvm-project/clang/lib/AST/AttrImpl.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/CXXABI.h b/contrib/llvm-project/clang/lib/AST/CXXABI.h index ca9424bcb7a4..9258a53fefeb 100644 --- a/contrib/llvm-project/clang/lib/AST/CXXABI.h +++ b/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 a/contrib/llvm-project/clang/lib/AST/CommentLexer.cpp b/contrib/llvm-project/clang/lib/AST/CommentLexer.cpp index 93531c06192d..61ce8979f13f 100644 --- a/contrib/llvm-project/clang/lib/AST/CommentLexer.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/Decl.cpp b/contrib/llvm-project/clang/lib/AST/Decl.cpp index 94a644cbe8e5..e6ce5a80dacd 100644 --- a/contrib/llvm-project/clang/lib/AST/Decl.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/DeclBase.cpp b/contrib/llvm-project/clang/lib/AST/DeclBase.cpp index 064012ba865c..9ee1cc083086 100644 --- a/contrib/llvm-project/clang/lib/AST/DeclBase.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp b/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp index 1780358cc348..0cf6e60b2a6c 100644 --- a/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp b/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp index ba827a79c022..f15dd78929e2 100644 --- a/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/DeclPrinter.cpp b/contrib/llvm-project/clang/lib/AST/DeclPrinter.cpp index 044eb8f8f8e5..c3f1d1544f79 100644 --- a/contrib/llvm-project/clang/lib/AST/DeclPrinter.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/Expr.cpp b/contrib/llvm-project/clang/lib/AST/Expr.cpp index 2530beb89d17..45e94847caee 100644 --- a/contrib/llvm-project/clang/lib/AST/Expr.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/ExprConcepts.cpp b/contrib/llvm-project/clang/lib/AST/ExprConcepts.cpp index 8cb8625e2a1a..c17453fb45fb 100644 --- a/contrib/llvm-project/clang/lib/AST/ExprConcepts.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp b/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp index 6f979d3264bb..40d0bd44b5d9 100644 --- a/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/FormatString.cpp b/contrib/llvm-project/clang/lib/AST/FormatString.cpp index 83b952116a5e..102bcca96a38 100644 --- a/contrib/llvm-project/clang/lib/AST/FormatString.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 5c8cb4274260..da538aa332ff 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.h b/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.h index 716f28551e58..124a6ff03f18 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/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 a/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeStmtGen.h b/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeStmtGen.h index d9c0b64ed4b8..3bc665b84b4d 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeStmtGen.h +++ b/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 a/contrib/llvm-project/clang/lib/AST/Interp/Context.h b/contrib/llvm-project/clang/lib/AST/Interp/Context.h index 4f25ff977b81..0627d9fb14f5 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/Context.h +++ b/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 a/contrib/llvm-project/clang/lib/AST/Interp/InterpBlock.h b/contrib/llvm-project/clang/lib/AST/Interp/InterpBlock.h index 0ccdef221c83..2d5386e60b8c 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/InterpBlock.h +++ b/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 a/contrib/llvm-project/clang/lib/AST/Interp/Pointer.h b/contrib/llvm-project/clang/lib/AST/Interp/Pointer.h index f2f6e0e76018..587531aec82a 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/Pointer.h +++ b/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 a/contrib/llvm-project/clang/lib/AST/Interp/PrimType.h b/contrib/llvm-project/clang/lib/AST/Interp/PrimType.h index f5f4f8e5c32d..de4bf9bf802e 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/PrimType.h +++ b/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 a/contrib/llvm-project/clang/lib/AST/Interp/Program.h b/contrib/llvm-project/clang/lib/AST/Interp/Program.h index c81ec777a5fe..ca985af8ad30 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/Program.h +++ b/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 a/contrib/llvm-project/clang/lib/AST/ItaniumMangle.cpp b/contrib/llvm-project/clang/lib/AST/ItaniumMangle.cpp index 7afc1250a36f..2e734e2b28cd 100644 --- a/contrib/llvm-project/clang/lib/AST/ItaniumMangle.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/Mangle.cpp b/contrib/llvm-project/clang/lib/AST/Mangle.cpp index 54dbf484f377..984da9909ce2 100644 --- a/contrib/llvm-project/clang/lib/AST/Mangle.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/MicrosoftCXXABI.cpp b/contrib/llvm-project/clang/lib/AST/MicrosoftCXXABI.cpp index 53d7e0b042ff..b7dc0e62e66a 100644 --- a/contrib/llvm-project/clang/lib/AST/MicrosoftCXXABI.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/OSLog.cpp b/contrib/llvm-project/clang/lib/AST/OSLog.cpp index 094c0102854b..4cc5def0651f 100644 --- a/contrib/llvm-project/clang/lib/AST/OSLog.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/PrintfFormatString.cpp b/contrib/llvm-project/clang/lib/AST/PrintfFormatString.cpp index fc658d5ba5c3..e5f356187988 100644 --- a/contrib/llvm-project/clang/lib/AST/PrintfFormatString.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/RecordLayoutBuilder.cpp b/contrib/llvm-project/clang/lib/AST/RecordLayoutBuilder.cpp index 3e39ec1c718d..61a30ead165e 100644 --- a/contrib/llvm-project/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/Stmt.cpp b/contrib/llvm-project/clang/lib/AST/Stmt.cpp index 4f76f6ec12ed..be19d3b2cce2 100644 --- a/contrib/llvm-project/clang/lib/AST/Stmt.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/StmtOpenMP.cpp b/contrib/llvm-project/clang/lib/AST/StmtOpenMP.cpp index b336a0637d5e..8a9f73d3dbf0 100644 --- a/contrib/llvm-project/clang/lib/AST/StmtOpenMP.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp b/contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp index b65a38d1e566..adc0720fe000 100644 --- a/contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/TemplateName.cpp b/contrib/llvm-project/clang/lib/AST/TemplateName.cpp index c8bd74f0b5bb..05d7d58b71c4 100644 --- a/contrib/llvm-project/clang/lib/AST/TemplateName.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/Type.cpp b/contrib/llvm-project/clang/lib/AST/Type.cpp index c771fe264b0c..774b3e94159d 100644 --- a/contrib/llvm-project/clang/lib/AST/Type.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/TypeLoc.cpp b/contrib/llvm-project/clang/lib/AST/TypeLoc.cpp index c3ed08d5a8b3..13aa54c48f66 100644 --- a/contrib/llvm-project/clang/lib/AST/TypeLoc.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/TypePrinter.cpp b/contrib/llvm-project/clang/lib/AST/TypePrinter.cpp index 2a33a69f288d..bba323f651aa 100644 --- a/contrib/llvm-project/clang/lib/AST/TypePrinter.cpp +++ b/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 a/contrib/llvm-project/clang/lib/AST/VTableBuilder.cpp b/contrib/llvm-project/clang/lib/AST/VTableBuilder.cpp index f938565c3cb4..24586d6b70d4 100644 --- a/contrib/llvm-project/clang/lib/AST/VTableBuilder.cpp +++ b/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 a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h index fa9d42247e24..3e9c4f31b84d 100644 --- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/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 a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 4f3efdb0a663..47db6b51966a 100644 --- a/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Analysis/CFG.cpp b/contrib/llvm-project/clang/lib/Analysis/CFG.cpp index 9ef3b5b6277a..8246854dc1b5 100644 --- a/contrib/llvm-project/clang/lib/Analysis/CFG.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp new file mode 100644 index 000000000000..3ad2ed640cc1 --- /dev/null +++ b/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 a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp new file mode 100644 index 000000000000..938f7338b640 --- /dev/null +++ b/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 a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp new file mode 100644 index 000000000000..51a86b727e33 --- /dev/null +++ b/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 a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 413e8d14bf0a..aaf6a834f5b3 100644 --- a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Analysis/UninitializedValues.cpp b/contrib/llvm-project/clang/lib/Analysis/UninitializedValues.cpp index a38ae34f4b81..811146e50b45 100644 --- a/contrib/llvm-project/clang/lib/Analysis/UninitializedValues.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp b/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp index fe35f77782c9..64bcb45a4cd8 100644 --- a/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp index 9b7ad96b949f..ac4b9d2cd5a2 100644 --- a/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp b/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp index a9f2d09924cd..87db131992e4 100644 --- a/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp index d811aeec84a0..b86cb7af69bd 100644 --- a/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp b/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp index b7408f39bdab..7e89b3f1b804 100644 --- a/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/TargetID.cpp b/contrib/llvm-project/clang/lib/Basic/TargetID.cpp index 59d416f0e015..3b8f4c13b9bf 100644 --- a/contrib/llvm-project/clang/lib/Basic/TargetID.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp index 646bbe8b7387..e3a2f30febe7 100644 --- a/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp index 4089a393b762..8e23cc4c421a 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h index 74745df3be8d..ebddce0c1c73 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp index c619d6cde41d..478a0233398d 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h index 40c658f3f40e..f074dac57f9b 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp index 50b0fc07b311..6266ed72cd5c 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h b/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h index 89a80ca6a39a..a281e2c2cd74 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp index c0cd8fa90ed6..ada5b97ed66d 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp index 7f7b44b658eb..1eb0317af60b 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h index 60701072ac4b..ac52eb219f54 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp index 770d37a1c1be..0680cad5b07c 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp index 5eeb77406c34..932102434801 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Basic/Targets/X86.h b/contrib/llvm-project/clang/lib/Basic/Targets/X86.h index c952b8c9a336..d1b66432e38b 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/X86.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/Address.h b/contrib/llvm-project/clang/lib/CodeGen/Address.h index 37c20291c0e8..3ac0f4f0d7e5 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/Address.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp b/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp index bacac0a20d4d..9ae5c870afc8 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp index e81c5ba5055c..10569ae2c3f9 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGAtomic.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGBlocks.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGBlocks.cpp index 7bb6dbb8a8ac..1f1de3df857c 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGBlocks.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGBlocks.h b/contrib/llvm-project/clang/lib/CodeGen/CGBlocks.h index 698ecd3d926a..e8857d98894f 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGBlocks.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp index 1982b40ff667..2b7862e618bd 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp index 9714730e3c4b..0b441e382f11 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.h b/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.h index ea839db7528e..b96222b3ce28 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp index d70f78fea6b4..a37ff8844e88 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGCall.h b/contrib/llvm-project/clang/lib/CodeGen/CGCall.h index c8594068c3fc..af63e1bddd2d 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGCall.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp index 8f99ff0d50ff..520e119ada26 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h b/contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h index 76f3a48f32f3..079a3e25d6dc 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGCleanup.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp index 2041d2a5b4c9..c1763cbbc5a0 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp index 6e189a61dd20..1a9080604a79 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h b/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h index 14ff0eeabd21..a76426e585c8 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp index e09279c1d455..18d658436086 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp index 3579761f1429..7b880c1354e1 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp index 34b4951a7f72..0fb7ec26a85e 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGExprAgg.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGExprAgg.cpp index 3b996b89a1d7..0968afd82064 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGExprAgg.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp index e32462eb635c..4e8933fffe03 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGObjC.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGObjC.cpp index b5bcf157036d..8cc609186f9e 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGObjC.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp index b2bf60d2c0fc..52b449090868 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp index 425d1a793439..e7dba4c8feab 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp index e35c15421520..db1c3ca191ca 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.h b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.h index b83ec78696d1..19754b0cfacc 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index 866454ddeaed..e09ea5e01b1a 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGRecordLayout.h b/contrib/llvm-project/clang/lib/CodeGen/CGRecordLayout.h index e6665b72bcba..5a3bcdf72f7b 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGRecordLayout.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index cf8313f92587..6f85bca8a201 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp index ef0068cd3b0c..520483bc08b6 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp index 4c11f7d67534..0db59dd2624c 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp index 482499da1b0f..c839376880c4 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp index e6adec6948af..50e1638924d1 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h index f76ce8a6400d..6db888dcec08 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp index 36b7ce87336c..d534cf182f5a 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h index f1565511f98a..e803022508a4 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CodeGenPGO.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenPGO.cpp index ab953c2c7d52..6657f2a91e3d 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CodeGenTBAA.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenTBAA.h index e8e006f41616..a65963596fe9 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenTBAA.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.cpp index 77721510dfd0..4839e22c4b14 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h index f8f7542e4c83..28b831222943 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp b/contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp index 1a15b09c7b2b..2979d92c8417 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/MacroPPCallbacks.h b/contrib/llvm-project/clang/lib/CodeGen/MacroPPCallbacks.h index 32906a000269..d249b5b0eb88 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/MacroPPCallbacks.h +++ b/contrib/llvm-project/clang/lib/CodeGen/MacroPPCallbacks.h @@ -17,7 +17,6 @@ namespace llvm { class DIMacroFile; -class DIMacroNode; } namespace clang { class Preprocessor; diff --git a/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 5971a7709304..e00ff2b68719 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/contrib/llvm-project/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp index f7b83c45022d..9fe7e5d1f5c3 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp index 85089cdb2200..fb81169003fc 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp +++ b/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 a/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.h b/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.h index aa8bbb60a75f..dfdb2f5f55bb 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.h +++ b/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 a/contrib/llvm-project/clang/lib/Driver/Driver.cpp b/contrib/llvm-project/clang/lib/Driver/Driver.cpp index 3b551ea94cc2..2e4ebc10e9ba 100644 --- a/contrib/llvm-project/clang/lib/Driver/Driver.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp b/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp index d31529748b62..403fac76f060 100644 --- a/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp index 50c89aaadc18..5fef1fb2ee5a 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp index f282f04b7931..6899f9360da5 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index be13d6d583ce..ca0ca4bf4eea 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.h index d47c402d4a42..0cdc2ec725e0 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.h +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp index 4013cf230026..16af9f6d7129 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h index 881b63bd36b9..862a2f2796be 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/ARM.h +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp index 65347a38490e..4386e395bc6c 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.h index 00e0490e069b..013cd2341e17 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.h +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp index 407f81a2ae09..1d30090ca21c 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp index ee573b89bed1..7324339efaa6 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp index de635f5816cf..05c58a8f43a8 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp index a7afec6963a1..bd1600d060c8 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp index 7aeadd84dfee..7a9570a686f4 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp index e413640abad3..af74b108e04e 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.h index a5ec33bd44f1..a5648d79d655 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.h +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp index 66e9d8ab525a..18cef288f018 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.h index 8f033de09bf6..c842773996ed 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.h +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVCSetupApi.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVCSetupApi.h index a890b85fd5e9..28e6e3e08e37 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVCSetupApi.h +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp index ecce2f062bd7..0501f9737404 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.cpp index af2e3a21a0af..e480d8bd8703 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.h index b3ef7b61dc3a..e0318ae8a3a2 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/PPCLinux.h +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp index 5783a733983a..bcf9147833dd 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.cpp index 50d03e79bbb0..27de69550853 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.h index 229f7018e3b5..a16ae3ca51fa 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/SPIRV.h +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp index 4cdeec7f9d8a..1e43796be1ff 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/VEToolchain.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp index a7298a9a71bf..3614272a5f74 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.h index c84e59675946..b4c3082a089a 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/WebAssembly.h +++ b/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 a/contrib/llvm-project/clang/lib/Driver/Types.cpp b/contrib/llvm-project/clang/lib/Driver/Types.cpp index 1bd187ad2fc0..8f6adc6c2ad1 100644 --- a/contrib/llvm-project/clang/lib/Driver/Types.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Edit/RewriteObjCFoundationAPI.cpp b/contrib/llvm-project/clang/lib/Edit/RewriteObjCFoundationAPI.cpp index a3d388a5ae44..589bf8d216ed 100644 --- a/contrib/llvm-project/clang/lib/Edit/RewriteObjCFoundationAPI.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/AffectedRangeManager.cpp b/contrib/llvm-project/clang/lib/Format/AffectedRangeManager.cpp index 7ad1f7070d0a..f69f65c5ddf1 100644 --- a/contrib/llvm-project/clang/lib/Format/AffectedRangeManager.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp b/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp index 4225d6b67b0e..b66584652bc8 100644 --- a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.h b/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.h index b1b2611263a9..0eb53cbd0293 100644 --- a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.h +++ b/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 a/contrib/llvm-project/clang/lib/Format/DefinitionBlockSeparator.cpp b/contrib/llvm-project/clang/lib/Format/DefinitionBlockSeparator.cpp new file mode 100644 index 000000000000..827564357f78 --- /dev/null +++ b/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 a/contrib/llvm-project/clang/lib/Format/DefinitionBlockSeparator.h b/contrib/llvm-project/clang/lib/Format/DefinitionBlockSeparator.h new file mode 100644 index 000000000000..31c0f34d6e19 --- /dev/null +++ b/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 a/contrib/llvm-project/clang/lib/Format/Format.cpp b/contrib/llvm-project/clang/lib/Format/Format.cpp index be01daa38929..04e2915e3af6 100644 --- a/contrib/llvm-project/clang/lib/Format/Format.cpp +++ b/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); @@ -430,6 +432,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 enumeration(IO &IO, FormatStyle::SpaceAroundPointerQualifiersStyle &Value) { @@ -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 a/contrib/llvm-project/clang/lib/Format/FormatToken.cpp b/contrib/llvm-project/clang/lib/Format/FormatToken.cpp index 57f8a5a45cbb..59d6f29bb54d 100644 --- a/contrib/llvm-project/clang/lib/Format/FormatToken.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/FormatToken.h b/contrib/llvm-project/clang/lib/Format/FormatToken.h index d410ede32240..a64329802ee3 100644 --- a/contrib/llvm-project/clang/lib/Format/FormatToken.h +++ b/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 a/contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp b/contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp index 7736a7042f86..c9166f4b17aa 100644 --- a/contrib/llvm-project/clang/lib/Format/FormatTokenLexer.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/NamespaceEndCommentsFixer.cpp b/contrib/llvm-project/clang/lib/Format/NamespaceEndCommentsFixer.cpp index 38ab5b9df76d..0c34c6126c21 100644 --- a/contrib/llvm-project/clang/lib/Format/NamespaceEndCommentsFixer.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.cpp b/contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.cpp index 5a89225c7fc8..b3a4684bead1 100644 --- a/contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.h b/contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.h index 7abd25687564..30ef96b8b0a7 100644 --- a/contrib/llvm-project/clang/lib/Format/QualifierAlignmentFixer.h +++ b/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 a/contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp b/contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp index 77dc0d683e5f..e4107525a7ff 100644 --- a/contrib/llvm-project/clang/lib/Format/SortJavaScriptImports.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp b/contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp index d83e837ca134..d0754e0c1112 100644 --- a/contrib/llvm-project/clang/lib/Format/TokenAnalyzer.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp index 505a7250572b..9d130dbb02eb 100644 --- a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.h b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.h index 6e5e62cd4d82..ecd9dbb0f864 100644 --- a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.h +++ b/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 a/contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp b/contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp index f652a4e7088f..0172a224335c 100644 --- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp index b6e55aab708f..35be2fa3eb62 100644 --- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h index 0c79723d50fc..3f64d57c7bff 100644 --- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.h +++ b/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 a/contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp b/contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp index 96a66da0f82b..0d2e507ac587 100644 --- a/contrib/llvm-project/clang/lib/Format/WhitespaceManager.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Format/WhitespaceManager.h b/contrib/llvm-project/clang/lib/Format/WhitespaceManager.h index 029f4159b748..42f958f68ba6 100644 --- a/contrib/llvm-project/clang/lib/Format/WhitespaceManager.h +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp b/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp index 52589677ca28..5f587cc1c023 100644 --- a/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp b/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp index 31e7ea3d243d..2465a7e2453b 100644 --- a/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp b/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp index b71addd84bfd..7f1ce3da7e7e 100644 --- a/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/ExtractAPIConsumer.cpp b/contrib/llvm-project/clang/lib/Frontend/ExtractAPIConsumer.cpp new file mode 100644 index 000000000000..cdf67f3c327a --- /dev/null +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp b/contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp index fb8132a5e40a..ad2e6039477f 100644 --- a/contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp b/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp index 629f99110661..a9023a7a1171 100644 --- a/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp b/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp index 5abbb3a235b4..34bbc365e647 100644 --- a/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 45df86ef91cd..1d0022bda474 100644 --- a/contrib/llvm-project/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp b/contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp index 3f2a78127477..3e8d582f90c2 100644 --- a/contrib/llvm-project/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp index 462aeda6e027..fc8fce4b42b8 100644 --- a/contrib/llvm-project/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp b/contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp index 8df7496c6ddd..1c4a76e68953 100644 --- a/contrib/llvm-project/clang/lib/Frontend/TextDiagnostic.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp b/contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp index 2759625ae254..f67dceea9135 100644 --- a/contrib/llvm-project/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/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 a/contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 8e18f33af0cb..8a8a13743762 100644 --- a/contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h b/contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h index 538556f394da..e447590393ec 100644 --- a/contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/__clang_hip_runtime_wrapper.h b/contrib/llvm-project/clang/lib/Headers/__clang_hip_runtime_wrapper.h index 73021d256cba..10cec58ed12f 100644 --- a/contrib/llvm-project/clang/lib/Headers/__clang_hip_runtime_wrapper.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/avx2intrin.h b/contrib/llvm-project/clang/lib/Headers/avx2intrin.h index 5064c87c2bb1..e33514a60ff3 100644 --- a/contrib/llvm-project/clang/lib/Headers/avx2intrin.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/avx512bwintrin.h b/contrib/llvm-project/clang/lib/Headers/avx512bwintrin.h index 6aee8aed8487..522ef100bab1 100644 --- a/contrib/llvm-project/clang/lib/Headers/avx512bwintrin.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/avx512fintrin.h b/contrib/llvm-project/clang/lib/Headers/avx512fintrin.h index df298640523b..50e0e287d9fc 100644 --- a/contrib/llvm-project/clang/lib/Headers/avx512fintrin.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/avx512vlintrin.h b/contrib/llvm-project/clang/lib/Headers/avx512vlintrin.h index 0519dba59081..178c9dbc0e6e 100644 --- a/contrib/llvm-project/clang/lib/Headers/avx512vlintrin.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/cetintrin.h b/contrib/llvm-project/clang/lib/Headers/cetintrin.h index 4290e9d7355b..019cab0261e7 100644 --- a/contrib/llvm-project/clang/lib/Headers/cetintrin.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/cpuid.h b/contrib/llvm-project/clang/lib/Headers/cpuid.h index 6df1b4a11172..5d262a60735f 100644 --- a/contrib/llvm-project/clang/lib/Headers/cpuid.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/emmintrin.h b/contrib/llvm-project/clang/lib/Headers/emmintrin.h index 6e9c3032c21f..4618b808efc4 100644 --- a/contrib/llvm-project/clang/lib/Headers/emmintrin.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/limits.h b/contrib/llvm-project/clang/lib/Headers/limits.h index c653580bac4e..c2d3a7cf4353 100644 --- a/contrib/llvm-project/clang/lib/Headers/limits.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/opencl-c-base.h b/contrib/llvm-project/clang/lib/Headers/opencl-c-base.h index 9c81ddb5e2a7..06b78da63e69 100644 --- a/contrib/llvm-project/clang/lib/Headers/opencl-c-base.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/opencl-c.h b/contrib/llvm-project/clang/lib/Headers/opencl-c.h index 77a7a8b9bb3a..8fde2fa29899 100644 --- a/contrib/llvm-project/clang/lib/Headers/opencl-c.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/smmintrin.h b/contrib/llvm-project/clang/lib/Headers/smmintrin.h index 710e55aaa120..0df59c5fcc59 100644 --- a/contrib/llvm-project/clang/lib/Headers/smmintrin.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/stdatomic.h b/contrib/llvm-project/clang/lib/Headers/stdatomic.h index 1e47bcb2bacf..780bcc2dfea1 100644 --- a/contrib/llvm-project/clang/lib/Headers/stdatomic.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/stdint.h b/contrib/llvm-project/clang/lib/Headers/stdint.h index 192f653e95a1..4790c25a2774 100644 --- a/contrib/llvm-project/clang/lib/Headers/stdint.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/tmmintrin.h b/contrib/llvm-project/clang/lib/Headers/tmmintrin.h index bcffa8187801..cb9be2349de5 100644 --- a/contrib/llvm-project/clang/lib/Headers/tmmintrin.h +++ b/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 a/contrib/llvm-project/clang/lib/Headers/vaesintrin.h b/contrib/llvm-project/clang/lib/Headers/vaesintrin.h index f3c0807bb94a..294dcff2addd 100644 --- a/contrib/llvm-project/clang/lib/Headers/vaesintrin.h +++ b/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 a/contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.cpp b/contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.cpp index 84eabc3a210f..4ade8b8bb074 100644 --- a/contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.h b/contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.h index e5ce798025d9..d1f454f21239 100644 --- a/contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.h +++ b/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 a/contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp b/contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp index a0b60118a1a8..39c125c395ef 100644 --- a/contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Frontend/InitHeaderSearch.cpp b/contrib/llvm-project/clang/lib/Lex/InitHeaderSearch.cpp index ed1314f3b03d..ec7b1505c7bf 100644 --- a/contrib/llvm-project/clang/lib/Frontend/InitHeaderSearch.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Lex/Lexer.cpp b/contrib/llvm-project/clang/lib/Lex/Lexer.cpp index 38467a1835d0..89e89c7c1f17 100644 --- a/contrib/llvm-project/clang/lib/Lex/Lexer.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp b/contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp index ef7a5351953e..f3aefdd22b51 100644 --- a/contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp b/contrib/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp index cfee7a3c2513..f6c95a8b67c6 100644 --- a/contrib/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Lex/Pragma.cpp b/contrib/llvm-project/clang/lib/Lex/Pragma.cpp index 67daa5841983..eb7e7cbc4714 100644 --- a/contrib/llvm-project/clang/lib/Lex/Pragma.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Lex/Preprocessor.cpp b/contrib/llvm-project/clang/lib/Lex/Preprocessor.cpp index b026ae36fc0f..3c338a2b8123 100644 --- a/contrib/llvm-project/clang/lib/Lex/Preprocessor.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseCXXInlineMethods.cpp b/contrib/llvm-project/clang/lib/Parse/ParseCXXInlineMethods.cpp index 19cddc69ebfc..7330c2b7593d 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp b/contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp index 0c1f88bc51d1..f21938c81689 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp b/contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp index f5a6ffcff9e9..c08a586604b1 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp b/contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp index 09a3842f5809..fbf79a0a8746 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp b/contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp index 76c510ddd36c..2d38891c723f 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseInit.cpp b/contrib/llvm-project/clang/lib/Parse/ParseInit.cpp index 9d9c03d28a97..fd0faba9c1c1 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseInit.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseObjc.cpp b/contrib/llvm-project/clang/lib/Parse/ParseObjc.cpp index 9e145f57d61f..f493ac9b92ca 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseObjc.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp b/contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp index 300b022d83b9..8ad5edb1bcd6 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseOpenMP.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp b/contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp index 292ab03e8614..ee07775b6346 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseStmt.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseStmtAsm.cpp b/contrib/llvm-project/clang/lib/Parse/ParseStmtAsm.cpp index 3e9ce8fd668f..04c3a8700c10 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseStmtAsm.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseTemplate.cpp b/contrib/llvm-project/clang/lib/Parse/ParseTemplate.cpp index 45af61a3926a..f875e3bf43e8 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseTemplate.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp b/contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp index 35c9036fb27e..512993a5278e 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Parse/Parser.cpp b/contrib/llvm-project/clang/lib/Parse/Parser.cpp index 11113fa1a060..ffa1e0f027f1 100644 --- a/contrib/llvm-project/clang/lib/Parse/Parser.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Rewrite/HTMLRewrite.cpp b/contrib/llvm-project/clang/lib/Rewrite/HTMLRewrite.cpp index e9b678b69594..70ea2fcd3d04 100644 --- a/contrib/llvm-project/clang/lib/Rewrite/HTMLRewrite.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Rewrite/Rewriter.cpp b/contrib/llvm-project/clang/lib/Rewrite/Rewriter.cpp index 3b06afc76e16..8950bfb7c4dc 100644 --- a/contrib/llvm-project/clang/lib/Rewrite/Rewriter.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp b/contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp index b4dcc9759b99..ac5ad52c0b1d 100644 --- a/contrib/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/CodeCompleteConsumer.cpp b/contrib/llvm-project/clang/lib/Sema/CodeCompleteConsumer.cpp index 0a2ca54e244a..fefe20941f17 100644 --- a/contrib/llvm-project/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/OpenCLBuiltins.td b/contrib/llvm-project/clang/lib/Sema/OpenCLBuiltins.td index 38debc5aa9fc..df2f206041c1 100644 --- a/contrib/llvm-project/clang/lib/Sema/OpenCLBuiltins.td +++ b/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 a/contrib/llvm-project/clang/lib/Sema/Scope.cpp b/contrib/llvm-project/clang/lib/Sema/Scope.cpp index 51b0b24e57b7..499279a2659d 100644 --- a/contrib/llvm-project/clang/lib/Sema/Scope.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/Sema.cpp b/contrib/llvm-project/clang/lib/Sema/Sema.cpp index 734ed0f62ec6..20b4a9a5d4e6 100644 --- a/contrib/llvm-project/clang/lib/Sema/Sema.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaCXXScopeSpec.cpp b/contrib/llvm-project/clang/lib/Sema/SemaCXXScopeSpec.cpp index 8cecf6c6ab4f..4781d71080c9 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp index 4e83fa1fffca..c8fb36b8311a 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp b/contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp index 93c07ccc891f..01fdf51c60c3 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaConcept.cpp b/contrib/llvm-project/clang/lib/Sema/SemaConcept.cpp index 466e37831f66..ce99d4848cca 100755 --- a/contrib/llvm-project/clang/lib/Sema/SemaConcept.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaCoroutine.cpp b/contrib/llvm-project/clang/lib/Sema/SemaCoroutine.cpp index e89cecd08cca..e7e60b7e7daf 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaCoroutine.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp index 3c58f1d19c04..3252671991b7 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp index b6bd2e69629d..f04236ab96c3 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp index 01f0079198c7..16cdb7e57723 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp index d6e659e17069..d4fefc3d18d8 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaExceptionSpec.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExceptionSpec.cpp index 3af4c6f4bc41..29cb4be7b1ba 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp index d32b3f217aa0..7de43705c2b1 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp index 54f0242d2ca1..b34b744d7312 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp index 83006f9d804a..dfd93aa4638d 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp index bdc8e1e0b336..4702c405fb4e 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp b/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp index 635e93ba8460..af6ee24240ce 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaModule.cpp b/contrib/llvm-project/clang/lib/Sema/SemaModule.cpp index a4b9f3c242c1..747734f2d0ff 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaModule.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaObjCProperty.cpp b/contrib/llvm-project/clang/lib/Sema/SemaObjCProperty.cpp index 74c73ace3c5f..118afb81dd72 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaObjCProperty.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp b/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp index ba0481874577..ae91a6470471 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp b/contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp index 42b1340f9a65..483247aaa7c5 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaSYCL.cpp b/contrib/llvm-project/clang/lib/Sema/SemaSYCL.cpp index 815463307ecc..f8c713c8545d 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaSYCL.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp b/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp index 1d90759f2406..746eb82a5bdc 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp b/contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp index 2482f6d404ea..64a0b45feb98 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp b/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp index e9636d2b942e..22dd395d9943 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp b/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp index 7d4c000e7e90..7c6bb4c8a5f8 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 27ac2cd08f2a..1da0dfec3f23 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/SemaType.cpp b/contrib/llvm-project/clang/lib/Sema/SemaType.cpp index 7a038301a249..959f4903b030 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaType.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Sema/TreeTransform.h b/contrib/llvm-project/clang/lib/Sema/TreeTransform.h index 298a3f7a83d8..e43b3ca968eb 100644 --- a/contrib/llvm-project/clang/lib/Sema/TreeTransform.h +++ b/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 a/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp index f93e0d2ed1c4..d806fb9e1949 100644 --- a/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp index 2144befcdb14..1ab26e58a404 100644 --- a/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h b/contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h index 265a77fdb215..4a4cfcce156d 100644 --- a/contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h +++ b/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 a/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp index 65a780e67510..763fc9537c04 100644 --- a/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp b/contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp index f4882c7be3f7..4fd217cf7a6e 100644 --- a/contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp index 7cdd78b8adfb..7841fd82e370 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp index 66ef781871ec..e2209e3debfd 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 10ed6149528c..57080a84451a 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp index 517a5d78271b..aa70db041c76 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp index cd502241ef61..cf97439a468d 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h index ec6a7144fa45..e35ea4ef05dd 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h index 730a59977175..753adea0d14d 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Yaml.h b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Yaml.h index ec612dde3b8b..497189f4c160 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Yaml.h +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index b957bec7493e..e13387fb1fc8 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 637e4edfd778..302a971a15f2 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index 1ccb0de92fba..8d4e0bbb7dec 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp index 8edcef319088..bb3261bae3bf 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index dad8a7b3caae..0bd47ced15a5 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index f6ddcb763f9d..b152f9d80ef5 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/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 a/contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/ModelInjector.h b/contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/ModelInjector.h index d2016c3b112c..4db26028362f 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Frontend/ModelInjector.h +++ b/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 a/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp b/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp index acceec690c11..80a70252721d 100644 --- a/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp b/contrib/llvm-project/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp index 29787b8a8894..75d0d50d851f 100644 --- a/contrib/llvm-project/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp b/contrib/llvm-project/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp index c1e25c41f719..51e8439b6b79 100644 --- a/contrib/llvm-project/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Tooling/Syntax/Tree.cpp b/contrib/llvm-project/clang/lib/Tooling/Syntax/Tree.cpp index c813865e95cd..981bac508f73 100644 --- a/contrib/llvm-project/clang/lib/Tooling/Syntax/Tree.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Tooling/Transformer/Parsing.cpp b/contrib/llvm-project/clang/lib/Tooling/Transformer/Parsing.cpp index 242db2a16b43..4f41e2e90def 100644 --- a/contrib/llvm-project/clang/lib/Tooling/Transformer/Parsing.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Tooling/Transformer/SourceCodeBuilders.cpp b/contrib/llvm-project/clang/lib/Tooling/Transformer/SourceCodeBuilders.cpp index a1c99b60216b..7496e968469c 100644 --- a/contrib/llvm-project/clang/lib/Tooling/Transformer/SourceCodeBuilders.cpp +++ b/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 a/contrib/llvm-project/clang/lib/Tooling/Transformer/Stencil.cpp b/contrib/llvm-project/clang/lib/Tooling/Transformer/Stencil.cpp index 8b20ef34c3ff..348d04dbaf4a 100644 --- a/contrib/llvm-project/clang/lib/Tooling/Transformer/Stencil.cpp +++ b/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 a/contrib/llvm-project/clang/tools/driver/cc1_main.cpp b/contrib/llvm-project/clang/tools/driver/cc1_main.cpp index fd3b25ccb3cb..f648adeba483 100644 --- a/contrib/llvm-project/clang/tools/driver/cc1_main.cpp +++ b/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 a/contrib/llvm-project/clang/tools/driver/cc1as_main.cpp b/contrib/llvm-project/clang/tools/driver/cc1as_main.cpp index db3288d75281..6459d1534b39 100644 --- a/contrib/llvm-project/clang/tools/driver/cc1as_main.cpp +++ b/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 a/contrib/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/contrib/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index 547ec2c82cb3..f4bf4b19911a 100644 --- a/contrib/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/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 a/contrib/llvm-project/clang/utils/TableGen/MveEmitter.cpp b/contrib/llvm-project/clang/utils/TableGen/MveEmitter.cpp index 1a2532fbf53f..cc830c1d5416 100644 --- a/contrib/llvm-project/clang/utils/TableGen/MveEmitter.cpp +++ b/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 a/contrib/llvm-project/clang/utils/TableGen/NeonEmitter.cpp b/contrib/llvm-project/clang/utils/TableGen/NeonEmitter.cpp index ff552b66c0e2..a69fbe0e42dc 100644 --- a/contrib/llvm-project/clang/utils/TableGen/NeonEmitter.cpp +++ b/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 a/contrib/llvm-project/clang/utils/TableGen/RISCVVEmitter.cpp b/contrib/llvm-project/clang/utils/TableGen/RISCVVEmitter.cpp index 62eef830318f..4b80d6da72fa 100644 --- a/contrib/llvm-project/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/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; } |